【问题标题】:Why is garbage being printed for the first element in this array?为什么要为该数组中的第一个元素打印垃圾?
【发布时间】:2012-04-28 00:48:10
【问题描述】:
  #include <stdio.h>
  #include<string.h>
  #include<stdlib.h>

  int main()
  {
     char *words[] = {"mHello", "kWorld", "kHow", "9Are", "3You?"};
     char **parsed = malloc(5);
     int i;
     for (i = 0; i < 5; i++)
     {
        int n = strlen(words[i]);
        parsed[i] = malloc(n);
        strncpy(parsed[i], words[i] + 1, n);
        printf("[%s] ", parsed[i]); 
     }
     printf("\n----------------------\n");
     for (i = 0; i < 5; i++)
       printf("[%s] ", parsed[i]);
         return 0;
  }

parsed[i] 包含不带第一个字符的words[i]

输出是

 [Hello] [World] [How] [Are] [You?]
 ----------------------
 [▒▒ o] [World] [How] [Are] [You?]

为什么对parsed[0] 的第一个 printf 调用可以正常工作,而第二个却不能?

另外,如果我从words 中删除一个元素,则此代码可以正常工作。怎么回事?

【问题讨论】:

  • 哎呀,你是对的。我刚刚看到它,因此删除了我的评论。

标签: c string


【解决方案1】:

你的malloc 没有为指向字符串的指针分配正确的空间,它应该是

parsed = malloc(sizeof(char*)*5)

【讨论】:

  • 我希望 C 有一个直截了当的失败方式。当代码像这样随机运行时,我很难调试。
  • @user1033777 如果你尝试free 你的parsed[i],你可能会在尝试释放parsed[0] 时得到一个很好的信息段错误,因为进一步的mallocs 可能会破坏簿记数据为了那个原因。此外,valgrind 也有帮助。
  • 是的,free 确实会产生一个。我去看看 valgrind。
【解决方案2】:

对于初学者来说,**parsed 对于存储在那里的所有指针来说不够大。应该分配的

parsed=malloc(sizeof(*parsed)*5);

您可以像这样滚动单个字符串分配并将所有字符串复制到一个中:

parsed[i]=strdup(words[i]+1);

这也可以正确处理字符串长度,现在乍一看似乎可能存在一个问题。

【讨论】:

  • 内存会不会太多
  • @HunterMcMillen 为什么?它完全是正确的数量 - 是指针大小的 5 倍。
  • 我一直使用成语x=malloc(sizeof(*x)*n),不管x是什么类型的指针,它都可以。
【解决方案3】:

要添加到其他答案,您可以使用valgrind 跟踪此类内存错误。

如果您希望您的代码在这些情况下严重失败,另一种工具是address sanitizer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 2021-09-02
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    相关资源
    最近更新 更多