分段错误 - 不同的glib-c版本可以做类似的事吗?

时间:2012-02-26 13:18:20

标签: c segmentation-fault glibc

我在内存分配/释放方面遇到了一些麻烦。

在“64位机器”上运行一些没有错误的c代码。 如果我在32位机器上运行相同的代码(重新编译后,obv。)我有一些分段故障的麻烦。

这是我的glib-c版本:

  

包装:libc6
  新:是的   状态:已安装   自动安装:没有   版本:2.13-20ubuntu5   优先级:必填   部分:libs   维护者:Ubuntu开发人员   未压缩尺寸:10,7米   取决于:libc-bin(= 2.13-20ubuntu5),libgcc1,tzdata   建议:glibc-doc,debconf | debconf-2.0,locales   冲突:belocs-locales-bin,belocs-locales-bin,libc6-amd64,libc6-amd64,              prelink(< 0.0.20090925),prelink(< 0.0.20090925),tzdata(<              2007k-1),tzdata(< 2007k-1),tzdata-etch,tzdata-etch   中断:nscd(< 2.13),nscd(< 2.13),libc6(!= 2.13-20ubuntu5)   替换:belocs-locales-bin,belocs-locales-bin,libc6-amd64,libc6-amd64,             libc6(< 2.13-20ubuntu5)   提供:glibc-2.13-1   描述:libreria C GNU嵌入式:librerie condivise

在32位计算机上,版本为:

  

2.06-01

更重要的是,这里有一些令我疯狂的代码:

void estrai_libro (FILE* fileDescriptor, Libro* libroLetto) {

char* ptr_buf;
size_t n;
size_t lung;
ssize_t nread;

/* ---- questo blocco di istruzioni verrà utilizzato per tutti
    i campi della struttura Libro passata in input */
/* inizializzo ptr_buf e n rispettivamente a NULL e a 0 in moda da
   da sfruttare al meglio la getline(...)*/     
ptr_buf = NULL;
n = 0;
/* copio all'interno del buffer ptr_buf il contenuto di una riga
       del file; la funzione getline legge dal file fino a quando non
   incontra uno \n (ecco perchè io formatto gli input) */
nread = getline (&ptr_buf, &n, fileDescriptor);
/* calcolo la lunghezza della stringa letta */
lung = strlen (ptr_buf);
/* istanzio una zona di memoria della stessa dimensione della stringa
   letta e fatta puntare dal campo titolo della struttura Libro */
libroLetto->titolo = (char*) malloc (lung*sizeof(char));
/* inizializzo la zona di memoria istanziata con degli 0 */
memset (libroLetto->titolo, 0, sizeof(libroLetto->titolo));
/* copio la stringa letta e contenuta in ptr_buf nel campo titolo
   della struttura Libro passata in input (libroLetto). */
strcpy (libroLetto->titolo,ptr_buf);
free (ptr_buf);
/* ---- fine blocco*/
ptr_buf = NULL;
n = 0;
nread = getline (&ptr_buf, &n, fileDescriptor);
lung = strlen (ptr_buf);
libroLetto->autore = (char*) malloc (lung*sizeof(char));
memset (libroLetto->autore, 0, sizeof(libroLetto->autore));
strcpy (libroLetto->autore,ptr_buf);
free (ptr_buf);
ptr_buf = NULL;
n = 0;
nread = getline (&ptr_buf, &n, fileDescriptor);
lung = strlen (ptr_buf);
libroLetto->editore = (char*) malloc (lung*sizeof(char));
memset (libroLetto->editore, 0, sizeof(libroLetto->editore));
strcpy (libroLetto->editore,ptr_buf);
free (ptr_buf);
ptr_buf = NULL;
n = 0;
nread = getline (&ptr_buf, &n, fileDescriptor);
lung = strlen (ptr_buf);
libroLetto->data_pubblicazione = (char*) malloc (lung*sizeof(char));
memset (libroLetto->data_pubblicazione, 0, sizeof(libroLetto->data_pubblicazione));
strcpy (libroLetto->data_pubblicazione,ptr_buf);
free (ptr_buf);
ptr_buf = NULL;
n = 0;
nread = getline (&ptr_buf, &n, fileDescriptor);
lung = strlen (ptr_buf);
libroLetto->num_pagine = (char*) malloc (lung*sizeof(char));
memset (libroLetto->num_pagine, 0, sizeof(libroLetto->num_pagine));
strcpy (libroLetto->num_pagine,ptr_buf);
free (ptr_buf); 
ptr_buf = NULL;
n = 0;
nread = getline (&ptr_buf, &n, fileDescriptor);
lung = strlen (ptr_buf);
libroLetto->num_copie = (char*) malloc (lung*sizeof(char));
memset (libroLetto->num_copie, 0, sizeof(libroLetto->num_copie));
strcpy (libroLetto->num_copie,ptr_buf);
free (ptr_buf);
ptr_buf = NULL;
n = 0;
nread = getline (&ptr_buf, &n, fileDescriptor);
free (ptr_buf);
}

有人有想法吗?

我的第一个关于glib-c版本,但现在我可以'

达到32位机器并“更新”该lib。那么,有人可以发言吗?

编辑:为了清楚起见,分段错误在免费之前发生(ptr_buf)

3 个答案:

答案 0 :(得分:6)

 libroLetto->titolo = (char*) malloc (lung*sizeof(char));
 memset (libroLetto->titolo, 0, sizeof(libroLetto->titolo));

sizeof(libroLetto->titolo)是指针成员的大小,而不是分配的对象。 你想要的是:memset(libroLetto->titolo, 0, lung)

您可能还想在每次调用时检查getline函数的返回值,否则strlen可能会产生意外结果。

最后但并非最不重要:

lung = strlen (ptr_buf);
libroLetto->autore = (char*) malloc (lung*sizeof(char));

您没有为尾随空字符分配空间,您想要的是malloc(lung + 1)

答案 1 :(得分:0)

您无需进行所有此类复制。我想getline()已经为你做了分配。

void estrai_libro (FILE* fileDescriptor, Libro* libroLetto) {

char * ptr_buf;
size_t n;

ssize_t nread;

n = 0;
libroLetto->titolo = NULL;
nread = getline ( &libroLetto->titolo, &n, fileDescriptor);

libroLetto->autore = NULL;
n = 0;
nread = getline ( &libroLetto->autore, &n, fileDescriptor);

libroLetto->editore = NULL;
n = 0;
nread = getline ( &libroLetto->editore, &n, fileDescriptor);

libroLetto->data_pubblicazione = NULL;
n = 0;
nread = getline ( &libroLetto->data_pubblicazione, &n, fileDescriptor);

libroLetto->num_pagine = NULL;
n = 0;
nread = getline ( &libroLetto->num_pagine, &n, fileDescriptor);

libroLetto->num_copie = NULL;
n = 0;
nread = getline ( &libroLetto->num_copie, &n, fileDescriptor);

ptr_buf = NULL;
n = 0;
nread = getline ( &ptr_buf, &n, fileDescriptor);
free (ptr_buf);
}

仅供参考:在c99标准化readline()之前,已经存在不同版本的readline()。 (并在c.l.c中传播)。这些略有不同的功能签名。至少使用-Wall编译以检查函数原型不匹配。

更新:oops,这是getline(),这是readline(),但是使用最大警告进行编译无论如何都可能是一个好主意。

更新:getline作为gnu扩展开始,并在2008年由posix标准化。

答案 2 :(得分:0)

这是我的测试程序,证明确实存在问题。我也把它发送给了Ubuntu,但它还没有被发布:

以下是测试程序:


#include        <objc/Object.h>
#include        <dmalloc.h>

main (int argc, char *argv[]) {
  size_t len;
  char *fname;
  char *rootname = "TESTFILE";

  len   = strlen (rootname) + 1;
  fname = (char *) calloc (len,1);

  printf ("rootname=%s len=%d\n", rootname,len);
}

用这一行编译:

    gcc -o tst tst.m -ldmalloc

它给出了这个结果:

$ ./tst
rootname=TESTFILE len=9
Segmentation fault