2013-10-18 4 views
0

문장을 뒤집기 위해이 작은 프로그램을 만들었습니다. 은 그래서 주어진 : 그것은 줄 것이다 A B C 형 D 리버스 문자열 realloc() : 다음 크기가 유효하지 않습니다.

: D를

b를이 잘 작동 c를, 나는 여분의 편지를 추가 할 때까지. 나는 "ABCDE"하려고하면이 오류와 함께 마지막에

과 realloc()를 실패 : 잘못된 다음 크기 : 여기 *

0x0000000000602010 난 아직도 나는 코드

#define MAX_TEXT 100 

#include <stdio.h> 
#include <string.h> //strlen 
#include <stdlib.h> //realloc 


int main(int argc, char **argv) { 
    char text[MAX_TEXT] = { 0 };  
    char *parts = NULL; 

    printf("Insert string: "); 
    fgets(text,MAX_TEXT,stdin); 
    sscanf(text,"%[^\n]",text); //remove the \n 


    char **reverse = NULL; 
    char **extra = NULL; 
    int size = 0; 
    int i = 0; 

    parts = strtok (text," "); 
    while (parts != NULL) { 

     size += ((strlen(parts)+4) * sizeof(char)); 
     extra = realloc(reverse,size); 

     if (extra) { 
      reverse = extra; 
      reverse[i++] = parts; 
     }  
     else { 
      printf("Error allocating memory\n"); 
      exit(1); 
     } 

     parts = strtok (NULL, " "); 
    } 

    while (--i >= 0) { 
     printf("%s ",reverse[i]);     
    } 

    printf("\n"); 
} 

입니다 포인터를 사용하여 초보자가 포인터를 가리 키지 않으므로 도움이 될 것입니다. 감사합니다.

Ps : 저는 valgrind를 사용하여 시도했지만 realloc에서 잘못된 점이 있음을 지적했지만 정확히 무엇을 이해할 수 없습니다.

업데이트 된 코드 : chux 내가 무엇을하고 있었는데, 표시된대로 지금의 char *에 대한 할당하고 찰리 화상 표시에 따라

#define MAX_TEXT 500 

#include <stdio.h> 
#include <string.h> //strchr 
#include <stdlib.h> //realloc 


int main(int argc, char **argv) { 
    char text[MAX_TEXT] = { 0 };   

    printf("Insert string: "); 
    fgets(text,MAX_TEXT,stdin); 
    //sscanf(text,"%[^\n]",text); //remove the \n <-- Undefined behaviour :D "if copying takes place between objects that overlap, the behavior is undefined." 
    char *theEnter = strchr(text,'\n'); 
    if (theEnter) { 
     *theEnter = 0;//remove \n 
    }   

    char **reverse = NULL; 
    char **extra = NULL; 
    char *parts = NULL; 
    int size = 0; 
    int i = 0; 
    size_t increse_by = sizeof(char *); 

    parts = strtok (text," "); 
    while (parts != NULL) { 

     size += increse_by; //pointer to pointer so increase by the size of new pointer 
     extra = realloc(reverse,size); 

     if (extra) { 
      reverse = extra; 
      reverse[i++] = parts; 
     }  
     else { 
      printf("Error allocating memory\n"); 
      exit(1); 
     } 

     parts = strtok (NULL, " "); 
    } 

    while (--i >= 0) { 
     printf("%s ",reverse[i]);     
    } 

    printf("\n"); 
} 

, 나는 또한, \ n을하기 때문에 제거하기 위해 sscanf에서 기능과 사용 strchr과 제거 정의되지 않은 동작.

감사합니다.

+0

잘 작동합니다. 이 링크를 확인하십시오. http://ideone.com/ly8ws2 – Arpit

+0

아무 의미도 없습니다. OP는 정의되지 않은 동작을 얻고 있습니다. –

+2

OP는 char * 배열에 실제로 할당해야하는 경우 char * 및 문자열 자체에 대한 공간을 할당합니다. –

답변

2

귀하의 realloc이 충분한 공간을 할당하지 못했습니다. sizeof (char *)는 아마 당신의 컴퓨터에서 8이다. 아래 realloc은 strlen == 1 부분에 (1 + 4) * 1 = 5를 할당합니다. 문자열 포인터로는 충분하지 않습니다.

시도 extrareverse이 ** 문자 있다는 것을

size += ((strlen(parts)+4) * sizeof(char)); 

size += sizeof(char *); 

에 대한 이유를 변경. 그래서 그들은 문자열에 대한 포인터의 배열입니다. 이 배열은 각 루프에 대해 strtok()을 통해 더 커집니다. strtok()은 null로 끝나는 문자열을 반환합니다. 따라서 메모리를 할당 할 필요가 없습니다.

당신은이 경우에 필요하지 않습니다,하지만 당신은 할 수 :

reverse[i++] = strdup(parts); 

당신이 text에서 문자열의 복사본을 가리 키도록 reverse의 문자열을 원하는 경우가 아닌 내부 text 자체.

+1

'sscanf (text, "% [^ \ n]", text)'에 대한 생각은? 그것은 새롭거나 UB 다. 나는 int sscanf (const char * restrict s, const char * restrict format ...)에서'restrict' 때문에 UB라고 생각하고있다. – chux

+0

@chux, 저는 정말 오래된 학교입니다. 제한을 포함하여 최근 변경 사항을 따라 가지 못했습니다. 그래서 나는 그것에 대해 지능적으로 논평 할 수 없다. restrict가 포인터가 겹치지 않아야한다는 것을 의미한다면, 나는 포인터가 있다고 생각합니다. –

+0

@chux, 당신의 질문은 좋다, 당신은 StackOverflow에 물어보고, 사람들이해야 할 말을보아야한다. –

관련 문제