2016-03-10 88 views
1

我想实现从控制台读取的字符串(可以是任何长度)的dynamyc数组。但是它在循环中的realloc()调用上崩溃。代码:C - realloc导致崩溃

void kill(char **memory, int count) { 
     if (memory != NULL) { 
     for (int i = 0; i < count; i++) { 
      if (memory[i] != NULL) { 
       free(memory[i]); 
      } 
     } 
     free(memory); 
    } 
} 

char **getData(int *strCount, int *allocatedCount) { 
    int maxStrCount = 10; 
    int maxStrLength = 10; 
    char **data = malloc(sizeof(char *) * maxStrCount); 
    if (data == NULL) { 
     return NULL; 
    } 
    for (int i = 0; i < maxStrCount; i++) { 
     data[i] = malloc(sizeof(char) * maxStrLength); 
     if (data[i] == NULL) { 
      kill(data, i); 
      return NULL; 
     } 
    } 
    int i = 0; 
    int j = 0; 
    for (char ch = getchar(); ch != EOF; ch = getchar()) { 
     if (ch == '\n') { // if end of line 
      data[i][j] = '\0'; 
      i++; 
      j = 0; 
      if (i >= maxStrCount) { 
       // extend array 
       char **newData = realloc(data, sizeof(char *) * (maxStrCount * 2)); 
       if (newData == NULL) { 
        kill(data, maxStrCount); 
        return NULL; 
       } 
       maxStrCount *= 2; 
       data = newData; 
       for (int k = i; k < maxStrCount; k++) { 
        data[k] = malloc(sizeof(char) * maxStrLength); 
        if (data[k] == NULL) { 
         kill(data, k); 
         return NULL; 
        } 
       } 
      } 
     } else { // if not end of line 
      data[i][j] = ch; 
      j++; 
      if (j >= maxStrLength - 1) { // extend string 
       maxStrLength *= 2; 
       char *newStr = realloc(data[i], sizeof(char) * maxStrLength); // Here it crashes 
       if (newStr == NULL) { 
        kill(data, maxStrCount); 
        return NULL; 
       } 
       data[i] = newStr; 
      } 
     } 
    } 
    if (j > 0) { // in case of file doesn't end with empty line 
     data[i][j] = '\0'; 
     i++; 
    } 
    if (i == 0) { // in case of empty input 
     kill(data, maxStrCount); 
     return NULL; 
    } 
    *strCount = i; 
    *allocatedCount = maxStrCount; 
    return data; 
} 

出现在接下来的输入崩溃:

Lorem ipsum dolor sit 
amet, consectetur 
adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua 

它发生是这样的:它读取“排版IPS”,然后realloc的调用,然后读取“Lorem存有悲的” ,然后再次调用realloc,一切正常。然后它读取“amet,consectetur”(第2行)和“adipiscing elit,sed do eiusmod tempor”(第3行),然后尝试重新分配和崩溃。

我看着所有这些试图调试,但我仍然不知道它为什么会崩溃。

+2

旁白:如果使用'INT ch'而不是'为(字符CH = getchar(); ch!= EOF; ...' – chux

回答

2

您在所有字符串之间共享变量maxStrLength

您正在重新分配第2行的缓冲区,并增加了该缓冲区的范围maxStrLength;然而,当你正在阅读的下一行,它的缓冲区是较小的,所以你在这里写进去了,越界:

data[i][j] = ch; 
+0

@WeatherVane - 这里怎么回事:'maxStrLength * = 2;'?我可以让我的“好抓”回来吗:) –

+0

非常感谢!这个愚蠢的错误让我有点绝望。 – Rashe

+0

@WeatherVane - np,正确的是足够的奖励! –