【发布时间】:2016-04-19 06:12:00
【问题描述】:
我正在C 从事一个项目。该项目的目的是编写一个函数,该函数每次调用时都会返回文件的下一行。
我只能使用malloc、free 和read 函数。
我尝试过的代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "get_next_line.h"
int my_putstr(char *str)
{
int i;
if (str == NULL)
return (1);
i = 0;
while (str[i] != '\0')
{
write(1, &str[i], 1);
i = i + 1;
}
return (0);
}
char *my_strcpy(char *src, char *dest)
{
int i;
int r;
r = 0;
i = 0;
if (src == NULL)
return (dest);
while (dest != NULL && dest[i] != '\0')
i = i + 1;
while (src[r] != '\0')
{
dest[i] = src[r];
i = i + 1;
r = r + 1;
}
dest[i] = '\0';
return (dest);
}
int check_back_n(t_stock *stock)
{
int i;
if (stock->save == NULL)
return (1);
i = 0;
while (stock->save[i] != '\0')
{
if (stock->save[i] == '\n')
return (0);
i = i + 1;
}
return (1);
}
int my_realloc(t_stock *stock)
{
if ((stock->temp = malloc(sizeof(char) *
(READ_SIZE * stock->counter) + 1)) == NULL)
return (1);
stock->temp = my_strcpy(stock->save, stock->temp);
free(stock->save);
if ((stock->save = malloc(sizeof(char) *
(READ_SIZE * (stock->counter + 1)) + 1)) == NULL)
return (1);
stock->save = my_strcpy(stock->temp, stock->save);
free(stock->temp);
return (0);
}
char *fill_over(t_stock *stock, char *over)
{
stock->r = 0;
stock->i = 0;
while (stock->save[stock->i] != '\n')
stock->i = stock->i + 1;
stock->save[stock->i] = '\0';
stock->i = stock->i + 1;
if ((over = malloc(sizeof(char) * READ_SIZE) + 1) == NULL)
return (NULL);
while (stock->save[stock->i] != '\0')
{
stock->save[stock->i] = over[stock->r];
stock->save[stock->i] = '\0';
stock->i = stock->i + 1;
stock->r = stock->r + 1;
}
return (over);
}
char *get_next_line(const int fd)
{
t_stock stock;
static char *over;
stock.counter = 2;
if ((stock.save = malloc(sizeof(char) * READ_SIZE) + 1) == NULL)
return (NULL);
stock.save = my_strcpy(over, stock.save);
free(over);
while (check_back_n(&stock) == 1)
{
if (my_realloc(&stock) == 1)
return (NULL);
if ((stock.buffer = malloc(sizeof(char) * READ_SIZE) + 1) == NULL)
return (NULL);
if ((stock.read_return = read(fd, stock.buffer, READ_SIZE)) == -1 ||
(stock.read_return == 0))
return (stock.save);
stock.counter = stock.counter + 1;
stock.save = my_strcpy(stock.buffer, stock.save);
free(stock.buffer);
}
if ((over = fill_over(&stock, over)) == NULL)
return (NULL);
return (stock.save);
}
int main()
{
char *s;
int fd;
fd = open("test", O_RDONLY);
while (s = get_next_line(fd))
{
my_putstr(s);
write(1, "\n", 1);
free(s);
}
return (0);
}
当我尝试运行代码时,出现以下错误:
*** Error in `./a.out': free(): invalid pointer: 0x0000000002024031 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7283f)[0x7fbb5b3f383f]
/lib64/libc.so.6(+0x780ae)[0x7fbb5b3f90ae]
/lib64/libc.so.6(+0x78db6)[0x7fbb5b3f9db6]
./a.out[0x400a38]
./a.out[0x400ab4]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fbb5b3a2b05]
./a.out[0x4005c9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:07 3146955 /home/degana_r/rendu/CProgElem/GetNextLine/CPE_2015_getnextline/a.out
00600000-00601000 r--p 00000000 08:07 3146955 /home/degana_r/rendu/CProgElem/GetNextLine/CPE_2015_getnextline/a.out
00601000-00602000 rw-p 00001000 08:07 3146955 /home/degana_r/rendu/CProgElem/GetNextLine/CPE_2015_getnextline/a.out
02024000-02045000 rw-p 00000000 00:00 0 [heap]
7fbb5b16a000-7fbb5b180000 r-xp 00000000 08:05 157433 /lib64/libgcc_s.so.1
7fbb5b180000-7fbb5b37f000 ---p 00016000 08:05 157433 /lib64/libgcc_s.so.1
7fbb5b37f000-7fbb5b380000 r--p 00015000 08:05 157433 /lib64/libgcc_s.so.1
7fbb5b380000-7fbb5b381000 rw-p 00016000 08:05 157433 /lib64/libgcc_s.so.1
7fbb5b381000-7fbb5b51f000 r-xp 00000000 08:05 147837 /lib64/libc-2.19.so
7fbb5b51f000-7fbb5b71e000 ---p 0019e000 08:05 147837 /lib64/libc-2.19.so
7fbb5b71e000-7fbb5b722000 r--p 0019d000 08:05 147837 /lib64/libc-2.19.so
7fbb5b722000-7fbb5b724000 rw-p 001a1000 08:05 147837 /lib64/libc-2.19.so
7fbb5b724000-7fbb5b728000 rw-p 00000000 00:00 0
7fbb5b728000-7fbb5b748000 r-xp 00000000 08:05 162636 /lib64/ld-2.19.so
7fbb5b91e000-7fbb5b921000 rw-p 00000000 00:00 0
7fbb5b946000-7fbb5b948000 rw-p 00000000 00:00 0
7fbb5b948000-7fbb5b949000 r--p 00020000 08:05 162636 /lib64/ld-2.19.so
7fbb5b949000-7fbb5b94a000 rw-p 00021000 08:05 162636 /lib64/ld-2.19.so
7fbb5b94a000-7fbb5b94b000 rw-p 00000000 00:00 0
7ffc76b9d000-7ffc76bbe000 rw-p 00000000 00:00 0 [stack]
7ffc76be8000-7ffc76bea000 r-xp 00000000 00:00 0 [vdso]
7ffc76bea000-7ffc76bec000 r--p 00000000 00:00 0 [vvar]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
【问题讨论】:
-
你自己已经做了哪些调试?
-
我已经摆脱了 2 个免费调用(get_next_line 中的 free(stock.buffer) 和 my_realloc 中的 free(stock->save))。这让我可以让函数 get_next_line 工作一次,但是当我多次调用它时,它给了我链接的错误
-
首先,请将错误作为文本而不是图像放入问题中。其次,摆脱
free调用几乎肯定不是解决问题的正确方法,因为它会导致内存泄漏。但听起来您并没有用尽所有的调试选项。如何在启用调试的情况下构建代码 (-g) 以获得更好的错误输出?在调试器中运行程序或使用调试打印语句来显示所有正在分配和释放的指针值怎么样?运行valgrind 来帮助您查找错误如何? -
你怎么知道你分配的是内存(因为没有调试的证据来验证)?由于内存损坏或其他错误,被释放的指针可能无效。或者它可能已经被释放(即双重释放)。因此建议跟踪所有分配和释放的指针值或运行 valgrind。如果您知道如何调试,请继续进行一些调试并与我们分享您的发现。
-
错误输出中显示的地址未对齐,因此不太可能是
malloc返回的地址。可能由此代码引起:over = malloc(sizeof(char) * READ_SIZE) + 1。仔细看看,看看你能不能找出原因。