我在内存分配/释放方面遇到了一些麻烦。
在“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)
答案 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