2015-02-05 100 views
3

C代碼以下運行在我的Mac OS X環境很好,但如果我嘗試運行在Ubuntu的環境中,該代碼,我得到一個malloc斷言失敗,每當我把偶數輸入例如「1 2」,但奇數輸入「1 2 3」起作用。錯誤是。 (old_top ==(((mbinptr)(((char *))&((av) - > bins [((1) - 1)* 2])) - __builtin_offsetof(結構個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 * (爲size_t))) - 1)))& &((old_top) - >大小爲0x1 &)& &((無符號長整數)OLD_END & pagemask)== 0)」失敗。 Aborted(核心轉儲)SYSMALLOC:在Ubuntu環境下斷言失敗

我不知道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; 
} 
+0

的argv [I] = malloc的(的sizeof(char)的* strlen的(Y));犯規分配anough內存,你需要+ 1 – pm100 2015-02-05 20:37:26

+0

BTW的strdup會做的malloc和複製你 – pm100 2015-02-05 20:38:38

+0

@myaut我無法相信我錯過了的argv [計數器+ 1] = NULL;謝謝! – killerkev 2015-02-05 20:57:49

回答

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數組索引與0開始,所以對於長度爲N陣列+ 1個最後一個索引是N.因此,而不是寫入最後argv指針的,你寫NULL通過sysmalloc內部使用面積,從而引起故障。

更改此行argv[counter] = NULL;

還要注意有關strcpy的使用意見。

0

除的argv [計數器+ 1]通過myaut引用問題,這些行:

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

打印未保證是空終止字符串。

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

沒有爲空終止符分配足夠的空間(您需要strlen(y)+ 1)。 strncpy不會溢出緩衝區,但它也不會提供終結符。 printf()打印一個你沒有終止的字符串 - 如果它打印的是正確的東西,那麼argv [i]緩衝區後面跟着一個零字節。另外,我不認爲你需要第一個strtok()調用,因爲getline()已經爲你完成了這項工作,並且argv是一個令人困惑的變量名稱,因爲它與它的常用用法不同,線路輸入。雖然這些事情都不會導致你的崩潰。