我正在研究tail
Unix命令的实现,到目前为止这是我的代码:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
char *resize(char *data, int size)
{
char *newData = (char*) malloc((size + 1) * sizeof(char));
int counter;
for(counter = 0; counter < size; counter++)
newData[counter] = data[counter];
free(data);
return newData;
}
int printLines(char *data, int size)
{
int lines = 0, position, counter;
for(position = size - 1; position > -1; position--)
{
if (data[position] == '\n') lines++;
if (lines == 10) break;
}
if (lines == 10)
for(counter = position; counter < size; counter++)
{
write(STDOUT_FILENO, &data[counter], 1);
}
else write(STDOUT_FILENO, data, size);
return 0;
}
int stdIn(char *data, int size)
{
char buff, end = '\n';
int rState = 0;
while ((rState = read(STDIN_FILENO, &buff, 1)) > 0)
{
if(rState < 0)
{
if(errno == EINTR) rState = 0;
else
{
perror("read()");
return 1;
}
}
data = resize(data, size);
data[size - 1] = buff;
size++;
}
if(rState == 0) write(STDOUT_FILENO, &end, 1);
return 0;
}
int tailRead(char *data, char *fileName)
{
int size = 1;
data = (char*)malloc(size * sizeof(char));
if(fileName == 0 || fileName == "-")
{
if(stdIn(data, size) > 0) return 1;
}
else
{
}
printLines(data, size);
return 0;
}
int main(int argc, char *argv[])
{
char *data = 0;
int counter;
if(argc == 1)
{
tailRead(data, 0);
if(data > 0) return 1;
}
else for (counter = 1; counter < argc; counter++)
{
tailRead(data, argv[counter]);
if(data > 0) return 1;
}
return 0;
}
问题是resize()
函数中的某个地方出现了分段错误,当我在GDB中运行程序时,我得到了Program received signal SIGSEGV Segmentation fault. 0x00000000004006f7 in resize ()
。这告诉我resize()
中存在某种内存分配问题,但到目前为止我一直无法找到该错误。我该怎么办?
答案 0 :(得分:0)
int tailRead(char *data, char *fileName)
/* ... */
int main(int argc, char *argv[])
{
char *data = 0;
/* ... */
tailRead(data, 0);
}
您似乎期望在main()
data
中指向tailRead()
中分配的内存。事实并非如此。在tailRead()
data
中,data
指针main()
的副本只会更改副本,而不是原始指针。原始指针仍指向0
。
然后使用空指针调用resize()
,这当然会导致分段违规。
<强>解决方案强>
使用指向指针的指针来修改原始指针。
int tailRead(char **data, char *fileName)
{
int size = 1;
*data = (char*)malloc(size * sizeof(char));
/* ... */
}
int main(int argc, char *argv[])
{
char *data = 0;
/* ... */
tailRead(&data, 0);
/* ... */
}
stdIn()
存在同样的问题。它会更改data
,而不会将data
指针的更改反映在tailRead()
中的呼叫网站上。您将stdIn()
内存泄漏并继续使用悬空指针。
答案 1 :(得分:-1)
我认为你的问题就在这里......
for(counter = 0; counter < size; counter++)
newData[counter] = data[counter];
当计数器大于您为之前data[counter]
分配的值时,您正尝试访问malloc()
。我的意思是,你正在超越data
的(当前)合法结束。有意义吗?