2010-07-06 3 views
3
char *a=NULL; 

char *s=NULL; 

a=(char *)calloc(1,(sizeof(char))); 

s=(char *)calloc(1,(sizeof(char))); 

a="DATA"; 

memcpy(s,a,(strlen(a))); 

printf("%s",s); 

인쇄 이유를 알려주세요. 데이터 1/2½½½½½½ ■ ε ■ 데이터 만 인쇄하는 방법 ?? 감사합니다memcpy 문제가 발생했습니다

답변

2

strlen은 종결 자 '\ 0'이없는 문자 만 계산합니다. 이 터미네이터가 없으면 printf는 문자열의 끝 또는 끝을 알 수 없습니다.

해결책 : memcpy (s, a, (strlen (a) +1)); 귀하의

a="DATA"; 

+0

감사 .... 도움이되었습니다. – SPB

2

먼저 메모리를 할당 한 다음 문자열 리터럴을 사용하여 포인터를 다시 할당하여 메모리를 버립니다. calloc()에 대한 귀하의 주장도 매우 잘못되었습니다.

또한 memcpy()은 문자열 복사 기능이 아니며 터미네이터를 포함하지 않습니다. strcpy()을 사용해야합니다.

데이터 만 인쇄하는 가장 좋은 방법은

당신은 당신이 원하는 무엇에 더 명확해야
puts("DATA"); 

는, 포인터/할당/복사에 도움을받을 수있을 것 같다.

6

C의 문자열은 0 문자 값 (nul)으로 끝납니다.

strlen은 0보다 앞에있는 문자 수를 반환합니다.

그래서 0을 복사하지 않습니다.

printf는 0이 될 때까지 s 뒤에 오는 메모리 내용을 인쇄합니다.

또한 크기가 1 인 버퍼 만 생성하므로 s 이후의 데이터를 쓰고 리터럴로 설정하기 전에 메모리 calloc'd를 누설합니다.

문자열의 길이를 찾은 후 s에 대한 메모리를 할당하고, 더 많은 바이트를 할당하여 nul 터미네이터를 포함시킨 다음 s를 s에 복사합니다. 리터럴 "DATA"를 저장 한 후 C 런타임이 보게 될 경우에는 아무 것도 할당 할 필요가 없습니다.

1

"DATA"를 쓸 때 실제로 다른 변수의 메모리를 사용하기 위해 1 문자의 공간을 예약합니다 (4 자 + 문자열의 끝을 표시하는 후행 \0).

a=(char *)calloc(1,(sizeof(char))); 

이 예를 들어, 당신은 5 자 이상을 필요 :

당신은 너무 printf() 인쇄를 중지 알 것이다 DATA 문자열 후 종료 \0을 저장해야
a=(char *)calloc(5, (sizeof(char))); 
1

.

당신은 strcat으로 memcpy을 대체 할 수 :

strcat(s, a); 

가 수행해야합니다.

참고 그러나,에 버그 이전이 있다고 :

calloc(1,sizeof(char)) 

단일 바이트를 할당합니다! 확실히 충분하지 않습니다! 구현에 따라 프로그램이 중단되거나 중단되지 않을 수도 있습니다.

1

는 할당 된 메모리에 대한 포인터를 삭제 한 사용자. "DATA"를 메모리에 복사하지 않습니다. 그렇지만 저장하기에 충분하지 않을 것입니다. 이후

a=(char *)calloc(1,(sizeof(char))); 

은 단일 문자를 할당합니다. 동안

memcpy(s,a,(strlen(a))); 

은 (문자열 리터럴 "DATA")가 가리키는 내용을 s가 가리키는 메모리로 복사합니다. 그러나 다시 s은 할당 된 단일 문자를 가리키며, 1 문자 이상을 복사하면 무언가를 덮어 쓰게되고 버그가 발생합니다.

strlen(a)은 4 ("DATA"의 길이)를 제공하고 memcpy는 정확히 4자를 복사합니다. 그러나 문자열의 끝을 알기 위해 C는 마지막 "null"char ('\ 0')을 끝에 붙이기 위해 규칙을 사용합니다. 그래서 실제로 "DATA"는 메모리에서 'D' 'A' 'T' 'A' '\ 0'입니다.

모든 문자열 관련 함수는 null 바이트를 예상하며 문자를 찾을 때까지 인쇄를 중지하지 않습니다.

문자열을 복사하려면 strcpy (또는 strncpy) 대신 문자열을 복사하면 최종 바이트도 함께 복사됩니다. (strcpy은 대상 버퍼를 오버플로 할 수 있으므로 "안전하지 않습니다").

하지만 여기에서 볼 수있는 가장 큰 문제는 하나의 문자 (그리고 그 다음 휴지통)와 s만을위한 문자를 예약한다는 것입니다. 따라서 DATA \ 0은 아무 곳에도 맞지 않습니다.