为动态字符串列表分配内存

时间:2017-10-07 06:00:42

标签: c memory-management

int strings(void){
  int NumStrings = 3;
  char **strings = (char**) malloc(sizeof(char*) * NumStrings);
  int i;
  char * element = "Trevor";
  for(i = 0; i < NumStrings; i++){
     strings[i] = ((char*) malloc(sizeof(char) * strlen(element)+1));
  }
  strings[0] = "abcdef";
  strings[1] = "lemons";
  strings[2] = "zoozoo13333";
  for(i = 0; i < NumStrings; i++){
    printf("%s\n", strings[i]);
  }
}

为什么这不会引起seg故障?我没有为&#34; zoozoo13333&#34;分配足够的内存,但它仍然可以打印正常,并且不会丢失任何错误。难道阵列中只有足够的空间可以容纳6个字符的字符串吗?

2 个答案:

答案 0 :(得分:1)

你没有得到缓冲区溢出,因为你根本没有写入缓冲区。

strings[2] = "zoozoo13333";

不复制字符串,它只是将strings[2]更改为指向字符串文字的内存而不是使用malloc()分配的缓冲区。结果,你有一个内存泄漏,因为你已经分配了内存,但没有任何东西指向它。

要复制字符串,您必须使用strcpy()。如果你这样做,你会得到一个缓冲区溢出:

strcpy(strings[2], "zoozoo13333");

这会导致未定义的行为,因为您在缓冲区的末尾写入。它不一定会导致分段错误。见Why don't I get a segmentation fault when I write beyond the end of an array?

答案 1 :(得分:0)

  

我没有为“zoozoo13333”分配足够的内存,但它仍然存在   打印正常,不会出现任何错误。

你应该意识到每当你做"zoozoo13333"这样的事情时,内存已经分配给一堆字符(以及一个尾随的\0)。但是,这个内存恰好分配在一个你无法修改的区域。换句话说,您无法更改此字符串本身。当内存被分配(隐式)并且你的字符串有效时,它打印正常。

  

不应该在数组中只有足够的空间用于字符串   6个字符?

现在,strings[i]只是指向char的指针。执行此操作时,您正确分配指向char的指针:strings[2] = "zoozoo13333";。没有缓冲区溢出。如上所述,字符串的空间已经被放在其他地方。你失去的是使用malloc()获得的分配空间的句柄。因此,您无法释放此空间并且您有内存泄漏。