为什么我得到 free(): invalid pointer?
Why am I getting free(): invalid pointer?
我目前正在阅读 Robert Love 的 Linux System Programming,并且一直停留在处理所有五个错误情况的 read() 示例上。我收到 free(): invalid pointer
错误。我假设它与推进缓冲区有关,以防读取未完成。
如果我存储偏移量和 return 指向其原始位置的指针,它就会起作用。书中没有提到这一点。有没有更好的方法?
#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
int main()
{
int fd;
if( (fd = open("someFile.txt", O_CREAT | O_WRONLY | O_TRUNC, 0664)) < 0)
perror("open for write");
char * text = "This is an example text";
write(fd, text, strlen(text));
close(fd);
if( (fd = open("someFile.txt", O_RDONLY)) < 0)
perror("open");
char *buf;
if( (buf = (char *) calloc(50, sizeof(char))) == NULL )
perror("calloc");
int len = 50;
ssize_t ret;
/* If I store the offset in a variable it works */
off_t offset = 0;
while (len != 0 && (ret = read (fd, buf, len)) != 0) {
if (ret == -1) {
if (errno == EINTR)
continue;
perror ("read");
break;
}
len -= ret;
buf += ret;
offset += ret; // Offset stored here
}
if( close(fd) == -1 )
perror("close");
buf -= offset; // Here I return the pointer to its original position
free(buf);
return 0;
}
此代码中存在多个错误。
首先,perror
没有被正确使用,因为它只打印一个错误——这里也应该有代码来中止错误,所以后续代码不会尝试使用来自操作的结果失败。
其次,只有calloc
的结果才能免费赠送。结果保存在 buf
中,但随后的代码更改了 buf
的值并尝试释放更改后的值。将更改存储在 offset
中应该可以解决此问题,但这充其量是一种容易出错的解决方案。如果您有多个修改 buf
的代码路径,则必须确保每个代码路径也以相同的方式修改偏移量。
更好的方法是不修改 buf
,而是在读取中使用第二个指针变量,该变量初始化为 buf
的值,然后在每次读取后修改。
正如所指出的,给 calloc
的数字与 len
的初始化数字不同。这是滥用幻数的完美示例。 20 和 50 都应该用相同的符号(变量或常量或#define)替换,这样你就不会得到缓冲区溢出错误。
我目前正在阅读 Robert Love 的 Linux System Programming,并且一直停留在处理所有五个错误情况的 read() 示例上。我收到 free(): invalid pointer
错误。我假设它与推进缓冲区有关,以防读取未完成。
如果我存储偏移量和 return 指向其原始位置的指针,它就会起作用。书中没有提到这一点。有没有更好的方法?
#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
int main()
{
int fd;
if( (fd = open("someFile.txt", O_CREAT | O_WRONLY | O_TRUNC, 0664)) < 0)
perror("open for write");
char * text = "This is an example text";
write(fd, text, strlen(text));
close(fd);
if( (fd = open("someFile.txt", O_RDONLY)) < 0)
perror("open");
char *buf;
if( (buf = (char *) calloc(50, sizeof(char))) == NULL )
perror("calloc");
int len = 50;
ssize_t ret;
/* If I store the offset in a variable it works */
off_t offset = 0;
while (len != 0 && (ret = read (fd, buf, len)) != 0) {
if (ret == -1) {
if (errno == EINTR)
continue;
perror ("read");
break;
}
len -= ret;
buf += ret;
offset += ret; // Offset stored here
}
if( close(fd) == -1 )
perror("close");
buf -= offset; // Here I return the pointer to its original position
free(buf);
return 0;
}
此代码中存在多个错误。
首先,perror
没有被正确使用,因为它只打印一个错误——这里也应该有代码来中止错误,所以后续代码不会尝试使用来自操作的结果失败。
其次,只有calloc
的结果才能免费赠送。结果保存在 buf
中,但随后的代码更改了 buf
的值并尝试释放更改后的值。将更改存储在 offset
中应该可以解决此问题,但这充其量是一种容易出错的解决方案。如果您有多个修改 buf
的代码路径,则必须确保每个代码路径也以相同的方式修改偏移量。
更好的方法是不修改 buf
,而是在读取中使用第二个指针变量,该变量初始化为 buf
的值,然后在每次读取后修改。
正如所指出的,给 calloc
的数字与 len
的初始化数字不同。这是滥用幻数的完美示例。 20 和 50 都应该用相同的符号(变量或常量或#define)替换,这样你就不会得到缓冲区溢出错误。