【问题标题】:Getting sYSMALLOc error in c for no reason无缘无故在c中出现sysmalloc错误
【发布时间】:2014-04-05 20:21:51
【问题描述】:

我在 C 程序上收到一条 sSYSMALLOc 错误消息,我相信这个错误消息与我使用的 malloc 相关,而且我通过在 malloc 周围放置 printf 语句发现了这一点,它导致了这个问题。我看不出有什么问题。有什么解决办法吗?请帮忙,代码如下。 此外,它运行了一段时间,然后就坏了。与错误信息,如下。

program: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr)
(((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof 
(struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) 
(old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk,
fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1)))
&& ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Aborted

node * new(char c)
{   
    NODE *node = (NODE *)malloc(sizeof(NODE));  

    node->c = c;

    return node;    
}

编辑: 我刚刚发现以下代码可能是导致错误发生的原因。有人能看出其中有什么问题吗?

void move(char *string)
{
 int length = strlen(string);               
 node->s = (char *)malloc(length*sizeof(char));         

 strcpy(node->s, string);
}

这个函数将字符串参数复制到node->s

【问题讨论】:

  • 您的代码(我们看不到的部分)很可能会写入 malloced 内存之外的部分并丢弃内部 malloc 数据。换句话说,有一个错误。
  • 有道理,只是想弄清楚我将如何解决它。在我的程序中还有另外两个地方使用 malloc

标签: c malloc assert


【解决方案1】:
node * new(char c) {   
    NODE *node = malloc(sizeof(NODE));
    if(node) {  
     node->c = c;
    }
    return node;    
}

您上面的代码是正确的。但问题是您假设下一行是在执行此行之前的一些 printf 语句导致问题。这是不正确的。

上述错误消息表明您的程序(其他地方)的先前逻辑已损坏堆内存。此异常/错误消息是刚刚生效,而不是真正的问题。您应该尝试在 Linux 上使用一些动态工具(Valgrind)和在 Windows 上使用 WinDBG/PageHeap 来确定程序中内存损坏的根本原因。

编辑 您可能想查看我之前关于如何使用 Valgrind 和 GDB 调试程序的帖子:https://stackoverflow.com/a/22658693/2724703

为了简单的使用,你可以使用下面的命令(如果你的程序是a.out)

$valgrind ./a.out

【讨论】:

  • 我将尝试使用 Valgrind,试图弄清楚如何使用它,因为我以前从未使用过它。还有其他两个地方我使用 malloc。所以你会说我也应该仔细看看那些 malloc!
  • @Jordan:请查看已编辑的帖子,其中包含有关如何使用 Valgrind 的信息。关于您的第二点,是的,您应该验证您的 malloc 调用并检查是否存在任何溢出情况......但是,程序中加载的任何模块(第 3 方/库)可能会损坏内存,因此找出此类错误的最佳方法是使用动态工具(valgrind)。
  • 谢谢,正在尝试安装 Valgrind,现在这已成为第二个问题,不知道如何安装
【解决方案2】:

字符串以零字节结束。你需要比它的长度多一个字节(不要使用sizeof(char),它总是1)。所以代码

void move(char *string) {
  size_t length = strlen(string);               
  node->s = malloc(1+length); 
  if (!node->s) 
    { perror("malloc string"); exit(EXIT_FAILURE); };        
  strcpy(node->s, string);
}

或者干脆使用strdup(3)

void move(char *string) {
  node->s = strdup(string);
  if (!node->s)
     { perror("move strdup"); exit(EXIT_FAILURE); }
}

不要忘记 malloc(3) 可能会失败(在 Linux 上,您可以使用内置的 ulimit shell 降低一些限制来测试它,即为了测试目的获得 malloc 失败。)。

也使用valgrind(当然还有你的gdb调试器)。

顺便说一句,this old question 和你的很相似!

【讨论】:

  • 非常感谢,我认为在最后添加一个对程序有很大帮助。但是,使用 valgrind 我发现 1,264,549 个块中仍有 46,669,439 个字节仍然可以访问,那么我该如何清除呢?和 valgring 中的其他选项都是 0。你知道为什么吗?
  • @Jordan:我建议您发布一个不同的问题来跟踪此问题。这看起来与您当前的问题不同。
猜你喜欢
  • 2020-06-25
  • 1970-01-01
  • 1970-01-01
  • 2015-02-15
  • 1970-01-01
  • 2021-04-23
  • 2022-08-16
  • 2022-11-20
  • 1970-01-01
相关资源
最近更新 更多