【问题标题】:C segmentation fault using malloc'ed strings使用 malloc'ed 字符串的 C 分段错误
【发布时间】:2018-05-09 14:20:27
【问题描述】:

基本上,我的代码中有一个链表结构,

struct node{
  char* val;
  struct node *next;
};

然后我尝试对它做一些事情......

...
addr = malloc(sizeof(struct node));
addr->val = malloc(72);
addr->val = "";
snprintf(addr->val, 1000, "%s", ident);
...

... 这给了我 snprintf 的分段错误。 Valgrind 说以下内容

Process terminating with default action of signal 11 (SIGSEGV)
==10724==  Bad permissions for mapped region at address 0x40566B
==10724==    at 0x4EB0A32: vsnprintf (vsnprintf.c:112)
==10724==    by 0x4E8F931: snprintf (snprintf.c:33)
==10724==    by 0x4016CC: id (Analyzer.c:267)
...

相对于 C++,我对 C 相当陌生,但我认为在 char* 上调用 malloc 应该使其有效,特别是因为我可以初始化和打印它,所以我不明白为什么 snprintf 不会工作。 我还让我的程序打印出两个变量的地址,而 valgrind 抱怨的地址确实来自 addr->val。

我也尝试使用 strcpy 代替 snprintf,但结果相同。

谢谢。

【问题讨论】:

    标签: c segmentation-fault printf strcpy


    【解决方案1】:
    addr->val = malloc(72);
    

    此行动态分配 72 个字节并将该内存区域的地址分配给 addr->val

    addr->val = "";
    

    然后将addr->val 设置为指向字符串常量的地址,丢弃它之前包含的内存分配区域的地址,从而导致内存泄漏。

    当您尝试使用snprintf 时,您正在尝试写入字符串文字。由于这些通常存储在内存的只读部分中,因此尝试这样做会导致核心转储。

    不需要addr->val = "";。它会丢弃分配的内存;它不会将分配的内存设置为空字符串,这可能是您认为它会做的事情。即使有,也无用,因为snprintf 会覆盖任何可能存在的内容。

    【讨论】:

      【解决方案2】:

      代码

      addr->val = malloc(72);
      addr->val = "";             <====
      

      用“”覆盖val指针,静态区域的地址,由1个字符组成(值为0)。删除此行。

      snprintf(addr->val, 1000, "%s", ident);
      

      在您只分配 72 个字符时接受 1000 的长度。

      snprintf(addr->val, 72, "%s", ident);
      

      更好。

      【讨论】:

        【解决方案3】:
        addr->val = malloc(72);
        addr->val = "";
        

        第二行将addr-&gt;val 重新分配给只读部分(字符串文字所在的位置)中的地址,并丢弃来自malloc 的分配地址,这可能导致潜在的内存泄漏。

        我知道你想清除它。要分配字符串,您应该使用strcpy()

        strcpy(addr->val, "");
        

        但既然要清空,最简单的方法是把第一个字符设置为零:

        addr->val[0] = '\0';
        

        此外,您正在尝试做一项可能有害的工作:

        snprintf(addr->val, 1000, "%s", ident);
        

        您打算分配 72 个字节,但为什么我们的第二个参数要达到 1k?将其更改为更安全的数字:

        snprintf(addr->val, 72, "%s", ident);
        

        到那时一切都会好起来的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-07
          • 2023-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-12
          相关资源
          最近更新 更多