繁体   English   中英

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

[英]Properly using/creating dynamic cstrings in C with malloc?

以下代码总是段错误:

  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?

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

 strcpy(test3, "abcd"); 

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

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

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

您需要使用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;
}

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

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

test3 = "asdf";

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

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

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

我用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的堆上的存储,并且显然是可寻址的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM