2012-01-13 8 views
0

저는 C가 처음이므로 실수를 바로 잡으십시오. Malloc은 C 문자열에 대해 쓰레기가 있습니까?

// some variables declared here like int array_size 
char* cmd = (char*)malloc(array_size*sizeof(char)); 
for(;;){ 
    // code here sets cmd to some string 
    free(cmd); 
    array_size = 10; 
    cmd = (char*)malloc(array_size*sizeof(char)); 
    // print 1 
    printf(cmd); 
    printf("%d\n", strlen(cmd)); 

    // repeat above for some time and then break 

} 

그래서 나는 잠시 동안 루프를 수행하고 출력 무엇을 참조하십시오

나는 약간 이렇게되면 일부 코드가 있습니다. 내가 예상 한 것은 문자열이 비어 있고 길이가 0이 될 때마다였습니다. 그러나 그 경우는 아닙니다. 분명히 때때로 malloc은 정크로 메모리를 가져오고 쓰레기와 메모리는 길이가 있습니다! = 0 그래서 malloc이 반환 될 때 새로운 char 문자열의 모든 char을 '\ 0'으로 설정하여이 문제를 해결하려고했습니다. 그러나, 나는 정말로 내가 뭔가 잘못했다고 확신한다. 문자열을 풀고 첫 번째 malloc과 달리 문자열에 정크가 들어있는 완전히 새로운 malloc을 수행 한 후에도 왜 그런가요? 내가 도대체 ​​뭘 잘못하고있는 겁니까?

+1

malloc의 반환 값의 형 변환이 나쁜 스타일이라고 생각하는 사람이 있고, 더 일반적으로'type * t = malloc (n * sizeof * t); ' 'type'을 변경해야 할 경우 첫 번째 행은 하나의 변경 만 필요로하고 두 번째 행은 3을 필요로하기 때문에'type * t = (type *) malloc (n * sizeof (type)); realloc' 호출은 변경 사항과 비교하여 2 가지 변경 사항이 없음). –

+0

잘못된 스타일 일뿐만 아니라, 그렇지 않으면 malloc 프로토 타입을 포함하는 헤더를 포함하는 것을 잊어 버리는 오류를 숨 깁니다. int가 포인터와 다른 너비 인 환경에서는 치명적일 수 있습니다. 다른 문제의 부분은 – paxdiablo

답변

9

malloc 방금 ​​메모리를 할당했습니다. 그것은 무엇이 메모리에 있는지에 대한 약속이 없습니다. 특히, 메모리를 초기화하지 않습니다. 할당 된 메모리를 0으로 만들려면 memset을 사용하여 수동으로 수행하거나 calloc (메모리가 0이 아닌 본질적으로 malloc)을 호출하면됩니다.

2

malloc은 메모리를 초기화하지 않습니다. 처음에는 운이 좋다.

또한 의 쓰레기이고 % 기호가 있으면 다른 문제가 발생할 수 있습니다.

+4

+1입니다. 올바른 방법 인'printf ("% s \ n", cmd);'를 지적했다면 더 좋을 것입니다. –

+0

@jonathan - 부적절한 포인트의 비트가 코드가 오류로 기록됩니다. 또한'string'은 null로 끝나지 않을 수도 있습니다! –

+0

몇 가지 문제를 피할 수 있지만 확실히 치료할 수는 없습니다. 맞아, 문자열은 할당 된 길이로 null로 끝나지 않을 것입니다. 그러나 바이트 값의 균등 분포를 가정하더라도 상당히 빨리 0 바이트가 발생할 것으로 예상됩니다. 실제로, 0 바이트는 전형적으로 전형적인 프로그램의 메모리 공간의 원시 스프의 다른 바이트보다 훨씬 더 자주 나타난다. –

0

아무 것도 잘못하지 않았습니다. malloc은 메모리가 0으로 설정된다는 것을 보증하지 않으며 단지 프로세스에만 속한다고합니다. 일반적으로 새로 할당 된 메모리를 불필요하게 0으로 설정하면 C에서 여러 클럭 사이클이 걸리는 절대로 명시 적으로 지워지지 않습니다. 필요할 경우 편리하게 설정할 수있는 'memset'메서드가 있습니다.

+0

그가 잘못한 점은 할당 된 메모리가 깨끗하게 초기화되었다고 가정하는 것일 수 있습니다. –

0

코드 세그먼트에 최소한 다음과 같은 문제가 있습니다.

  1. 당신은 이제까지 sizeof(char) 곱 할 필요가 없습니다 - 그것은 항상 하나입니다.

  2. malloc의 반환 값을 캐스팅합니다. 이렇게하면 malloc 프로토 타입과 함께 헤더를 포함하는 것을 잊어 버린 경우 (예 : int 반환 코드로 가정)와 같이 감지되는 오류를 숨길 수 있습니다.

  3. malloc은 메모리가있는 상태에서 수행 할 필요가 없으며 방금 해방 한 블록을 제공하지도 않습니다. 이후에 간단한 *cmd = '\0';을 사용하여 빈 문자열로 초기화 할 수 있습니다.malloc 모든 것이 필요한 경우이를 초기화 할 수 있습니다.

  4. printf (cmd)cmd에 무엇이 들어 있는지 모르는 경우 위험합니다. 형식 지정자 문자 (%)가 있으면 문제가 발생합니다. 더 좋은 방법은 printf ("%s", cmd)입니다.

+0

'printf ("% s", cmd);'조차도 cmd가 정의되지 않은 내용을 가지며 null로 끝나지 않을 수도 있기 때문에 문제가 발생할 수 있습니다. –

+0

@Ed, 나는 포인트 3 및/또는 "cmd가 무엇인지 알지 못하는 경우"에 해당한다고 생각합니다. – paxdiablo

관련 문제