sysmalloc:ubuntu环境下的断言失败

时间:2015-02-05 20:19:43

标签: c

下面的C代码在我的mac OS X环境中运行良好,但如果我尝试在ubuntu环境中运行此代码,每当我输入偶数个输入时,我得到一个malloc断言失败,例如“1 2” ,但奇数输入“1 2 3”有效。错误是。

a.out:malloc.c:2372:sysmalloc:断言`(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)'失败。 中止(核心倾销)

我不知道OS X和ubuntu环境之间的区别,所以如果有人能指出什么是错的我会很感激。我正在运行Ubuntu 14.04。它似乎在y!= NULL循环中崩溃

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>


void free_argv(char **argv,int counter)
{
    int i = 0;
    for(i=0;i<counter;i++)
    {
        free(argv[i]);
    }

    free(argv);
}

int main()
{
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    char **argv = NULL;
    int counter;
    int status;

    while ((read = getline(&line, &len, stdin)) != -1)
    {

        counter = 1;
        printf("$ ");
        char* x = strtok(line,"\n");

        int i = 0;

        while(x[i] != '\0')
        {
            if(x[i] == ' ')
            {
                counter++;
            }
            i++;
        }


        argv = malloc(sizeof(char*)*(counter+1));

        argv[counter+1] = NULL;

        i = 0;

        char* y = strtok(x," ");

        printf("user input:\n");
        while(y != NULL)
        {
            argv[i] = malloc(sizeof(char)*strlen(y));
            strncpy(argv[i],y,strlen(y));
            printf("      %s\n",argv[i]);
            y = strtok(NULL," ");
            i++;
        }
        free_argv(argv,counter);
    }
    return 0;
}

2 个答案:

答案 0 :(得分:2)

在这种情况下考虑使用valgrind - 它非常有用!它给了我什么:

==6454== Invalid write of size 8
==6454==    at 0x4008CE: main (sysmalloc.c:49)
==6454==  Address 0x51e0128 is 0 bytes after a block of size 40 alloc'd
==6454==    at 0x4C2C27B: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==6454==    by 0x4008B1: main (sysmalloc.c:47)

sysmalloc.c:49是argv[counter+1] = NULL; - 这是行引起的问题。请注意,在C数组中索引从零开始,因此对于长度为N + 1的数组,最后一个索引是N.因此,不是写入最后argv指针,而是将sysmalloc内部使用的区域写入NULL造成了错误。

将此行更改为argv[counter] = NULL;

另请注意有关strcpy用法的评论。

答案 1 :(得分:0)

除了myaut引用的argv [counter + 1]问题之外,这些行:

argv[i] = malloc(sizeof(char)*strlen(y));
strncpy(argv[i],y,strlen(y));
printf("      %s\n",argv[i]);

正在打印一个不保证以null结尾的字符串。

malloc(sizeof(char)*strlen(y));

没有为null终止符分配足够的空间(你需要strlen(y)+ 1)。 strncpy不会溢出缓冲区,但它也不会提供终结符。 printf()正在打印一个你没有终止的字符串 - 如果它打印出正确的东西,那么argv [i]缓冲区后跟一个零字节就是偶然的。

另外,我认为你不需要第一次strtok()调用,因为getline()已经为你完成了这项工作,并且argv是你变量的一个令人困惑的名字,因为它与命令行的常见用法不同输入。但是,这些都没有导致你的崩溃。