使用malloc在C中正确使用/创建动态cstrings?

时间:2013-08-07 23:31:40

标签: c malloc cstring

以下代码始终是段错误:

  char *test3 = (char *) malloc(sizeof(char) * 5);
  test3 = "asdf";
  printf("%s\n", test3);

以下代码不会出现段错误:

  char *test3 = (char *) malloc(sizeof(char) * 5);
  test3[0] = 'a';
  test3[1] = 'b';
  test3[2] = 'c';
  test3[3] = 'd';
  test3[4] = '\0';
  printf("%s\n", test3);

我想问题可能是如何将cstring文字分配给动态创建的cstring?

4 个答案:

答案 0 :(得分:2)

“填充”字符串的正确方法是:

 strcpy(test3, "abcd"); 

但是,我强烈建议您不要使用malloc [并且肯定不要使用(char *) malloc(...) - 因为这样可以隐藏一些相当讨厌的错误,这些错误会让你跳起来并至少抓住机会那一刻,因为bug确实有这样的倾向 - 你可能正在这样做,因为你正在编译你的C代码作为C ++代码,这是错误的,并教你像这样的坏习惯]。

使用malloc分配小字符串是一个很大的空间浪费。您的5个字符的字符串可能有16-32字节的开销,并将四舍五入为8或16个字节。所以总共可以使用48个字节来存储5个字节 - 这是一个很大的浪费空间。

答案 1 :(得分:0)

在您的情况下,不能为字符串值指定“=”。

您需要使用strcpy或sprintf函数。在程序结束时(或不再使用字符串时)不要忘记释放它! 例如:

#define BUFSIZE 5

int main(void) {
    char *test3 = malloc(sizeof(char) * BUFSIZE);
    snprintf(test3,BUFSIZE,"test");
    printf("%s\n", test3);
    free(test3);
    return 0;
}

或者你可以写:

int main(void) {
    char buf[BUFSIZE] = "test";
    printf("%s\n", buf);
    return 0;
}

答案 2 :(得分:0)

其他人(正确地)建议您将字符串复制到已分配的内存中。

这就是为什么你的方法是segfaulting:字符串“asdf”是一个字符串文字,在编译时它存储在rodata或只读数据中。程序尝试时

test3 = "asdf";

它试图创建指向rodata的指针。 C不允许指向rodata,所以你的语句不仅不起作用,而且是seg错误。

第二种方法很好,因为你没有修改指针,而是指向它。

答案 3 :(得分:0)

首先,谢谢你对这个问题有一个有趣的皱纹。

我用Eclipse / Microsoft C运行你的代码并没有得到分段错误,它按预期打印“asdf”。

但是,这并不意味着或暗示您没有遇到分段错误。您的结果意味着检查编译器如何实现这两个语句:

   char *test3 = (char *) malloc(sizeof(char) * 5);

在堆上分配存储空间并将指针test3设置为指向该位置。 下一个语句也会更新相同的指针。

   test3 = "asdf";

但是,在这种情况下,test3指向文字“asdf”,其中存储了文字。有些编译器会生成一个字符串字符串并将它们存储在可执行文件中的某个位置,因此对于某些编译器来说,这些字符串无法修改。

那么为什么编译器会存储无法访问的文字?没有意义,因此问题是:你使用什么C编译器?什么版本的C坚持?

要解决可能是编译器错误的问题,并仍然将test3指向文字,请尝试? (同样,C编译器在实现语言结构的方式和方式方面也存在差异。)

  const char *literal = "asdf";  // also try without a const stmt 
  // other code here
  test3 = literal;

最后,在第二个示例中,正在修改malloc ed的堆上的存储,并且显然是可寻址的。