sysmalloc:ubuntu环境上的断言失败

sysmalloc:ubuntu环境上的断言失败,c,C,下面的C代码在我的mac OS X环境中运行良好,但如果我尝试在ubuntu环境中运行此代码,每当我输入偶数个输入(如“12”)时,就会出现malloc assert失败,但奇数输入“1 2 3”起作用。错误是 a、 out:malloc.c:2372:sysmalloc:Assertion`(old_top==((mbinptr)((char*)和((av)->bin[(1)-1)*2])-((struct malloc_chunk,fd))和old_size==0)(unsigned lon

下面的C代码在我的mac OS X环境中运行良好,但如果我尝试在ubuntu环境中运行此代码,每当我输入偶数个输入(如“12”)时,就会出现malloc assert失败,但奇数输入“1 2 3”起作用。错误是

a、 out:malloc.c:2372:sysmalloc:Assertion`(old_top==((mbinptr)((char*)和((av)->bin[(1)-1)*2])-((struct malloc_chunk,fd))和old_size==0)(unsigned long)(old_size)>=(unsigned long)(unsigned long)(unsigned long)(unsigned long)(unsigned long)(unsigned long)(unsigned long)(unsigned long)((((((((((((((((((uu-builtin-offsetof)(struct)struct-malloc chunk,fd nextsize)))nextsize=))+))+(2)和sizu-sizu)sizu)sizu-siz&&((旧_-top)->size&0x1)&((无符号长)旧_-end&pagemask)==0)失败。 中止(堆芯转储)

我不知道OSX和ubuntu环境之间的区别,所以如果有人能指出问题所在,我将不胜感激。我正在运行Ubuntu 14.04。它似乎在y范围内崩溃了!=空循环

#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;
}
#包括
#包括
#包括
#包括
#包括
无效自由_argv(字符**argv,整数计数器)
{
int i=0;

对于(i=0;i请考虑在这种情况下使用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
指针,而是将NULL写入
sysmalloc
内部使用的区域,从而导致了故障

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


还要注意有关strcpy用法的注释。

除了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));
没有为空终止符分配足够的空间(您需要strlen(y)+1)。strncpy不会使缓冲区溢出,但也不会提供终止符。printf()正在打印您尚未终止的字符串-如果它打印的内容正确,则argv[i]缓冲区后面会有一个零字节


另外,我认为您不需要第一个strtok()调用,因为getline()已经为您完成了这项工作,而argv是一个令人困惑的变量名称,因为它不同于通常用作命令行输入的名称。但是,这两种情况都不会导致您的崩溃。

argv[I]=malloc(sizeof(char)*strlen(y));不分配足够的内存,您需要+1BTW的strdup将执行malloc并复制you@myaut我不敢相信我错过了argv[counter+1]=NULL;谢谢!