realloc():使用 argc 和 argv 时出现无效指针错误
realloc(): invalid pointer error when using argc and argv
作为练习的一部分,我正在用 C 开发一个类似 grep 的小程序,它应该接收一个字符串和一些文件名,以便在引用的文件中查找该字符串。
我通过硬编码文件名和字符串使其工作:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int searchString(char *str1, char *str2) {
if (strstr(str1, str2) == NULL) {
return 0;
} else {
return 1;
}
}
void searchInFile(char *filename, char *str) {
FILE *f;
int lineno =0;
size_t len;
char *buffer;
f = fopen(filename, "r");
if (f != NULL) {
while (getline(&buffer, &len, f) != -1) {
lineno++;
if (searchString(buffer, str)) {
printf("[%s:%d] %s", filename, lineno, buffer);
}
}
}
fclose(f);
}
int main() {
searchInFile("loremipsum.txt", "dolor");
return 0;
}
但是一旦我修改代码以更改 int main() 行以添加 argc 和 argv,编译它并然后运行它,脚本returns一个错误信息。
修改为:
int main(int argc, char *argv[]) {
searchInFile("loremipsum.txt", "dolor");
return 0;
}
收到的错误:
* Error in `./a.out': realloc(): invalid pointer: 0x000056424999394d *
有人知道我为什么会收到这个错误吗?
您使用 getline()
的主要问题是在将 buffer
作为 lineptr
参数和 len
传递之前无法初始化 len = 0;
和 buffer = NULL;
作为 n
参数。 man 3 getline
,说明:
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
...
If *lineptr is set to NULL and *n is set 0 before the call, then
getline() will allocate a buffer for storing the line."
除非您初始化 lineptr
的指针和 n
的值,否则它们将包含不确定(垃圾)值,这将阻止 getline
自动正确处理分配。
解决这些问题,提供一些小的清理,并允许将文件名和搜索项作为第一个和第二个参数传递给您的程序,您可以执行类似于以下操作的操作:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* consider adding parameter for case-insensitive search */
int searchstring (const char *str1, const char *str2)
{
if (strstr (str1, str2) == NULL)
return 0;
else
return 1;
}
int searchinfile (const char *filename, char *str)
{
int lineno = 0;
size_t len = 0;
char *buffer = NULL;
FILE *f = fopen (filename, "r");
if (!f) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", filename);
return 1;
}
/* read each line into buffer, search for searchstring */
while (getline (&buffer, &len, f) != -1) {
lineno++;
if (searchstring (buffer, str))
printf("[%s:%d] %s", filename, lineno, buffer);
}
fclose (f); /* close file */
return 0;
}
int main (int argc, char **argv) {
if (argc < 3) { /* validate at least 2 arguments given */
fprintf (stderr, "error: insufficient input.\n"
"usage: %s <file> <searchstring>\n", argv[0]);
return 1;
}
/* search file argv[1] for string argv[2] */
if (searchinfile (argv[1], argv[2]))
fprintf (stderr, "unable to search '%s'.\n", argv[1]);
return 0;
}
示例输入文件
$ cat dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
例子Use/Output
$ /tmp/tmp-david/greplite dat/captnjack.txt Sea
[dat/captnjack.txt:4] On the Seven Seas.
请注意代码中的注释——传递一个附加参数以指示是否应执行 case-insensitive 搜索(然后在搜索之前将行和 search-term 转换为 lower-case)。
检查一下,如果您还有其他问题,请告诉我。
作为练习的一部分,我正在用 C 开发一个类似 grep 的小程序,它应该接收一个字符串和一些文件名,以便在引用的文件中查找该字符串。
我通过硬编码文件名和字符串使其工作:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int searchString(char *str1, char *str2) {
if (strstr(str1, str2) == NULL) {
return 0;
} else {
return 1;
}
}
void searchInFile(char *filename, char *str) {
FILE *f;
int lineno =0;
size_t len;
char *buffer;
f = fopen(filename, "r");
if (f != NULL) {
while (getline(&buffer, &len, f) != -1) {
lineno++;
if (searchString(buffer, str)) {
printf("[%s:%d] %s", filename, lineno, buffer);
}
}
}
fclose(f);
}
int main() {
searchInFile("loremipsum.txt", "dolor");
return 0;
}
但是一旦我修改代码以更改 int main() 行以添加 argc 和 argv,编译它并然后运行它,脚本returns一个错误信息。 修改为:
int main(int argc, char *argv[]) {
searchInFile("loremipsum.txt", "dolor");
return 0;
}
收到的错误:
* Error in `./a.out': realloc(): invalid pointer: 0x000056424999394d *
有人知道我为什么会收到这个错误吗?
您使用 getline()
的主要问题是在将 buffer
作为 lineptr
参数和 len
传递之前无法初始化 len = 0;
和 buffer = NULL;
作为 n
参数。 man 3 getline
,说明:
ssize_t getline(char **lineptr, size_t *n, FILE *stream); ... If *lineptr is set to NULL and *n is set 0 before the call, then getline() will allocate a buffer for storing the line."
除非您初始化 lineptr
的指针和 n
的值,否则它们将包含不确定(垃圾)值,这将阻止 getline
自动正确处理分配。
解决这些问题,提供一些小的清理,并允许将文件名和搜索项作为第一个和第二个参数传递给您的程序,您可以执行类似于以下操作的操作:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* consider adding parameter for case-insensitive search */
int searchstring (const char *str1, const char *str2)
{
if (strstr (str1, str2) == NULL)
return 0;
else
return 1;
}
int searchinfile (const char *filename, char *str)
{
int lineno = 0;
size_t len = 0;
char *buffer = NULL;
FILE *f = fopen (filename, "r");
if (!f) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", filename);
return 1;
}
/* read each line into buffer, search for searchstring */
while (getline (&buffer, &len, f) != -1) {
lineno++;
if (searchstring (buffer, str))
printf("[%s:%d] %s", filename, lineno, buffer);
}
fclose (f); /* close file */
return 0;
}
int main (int argc, char **argv) {
if (argc < 3) { /* validate at least 2 arguments given */
fprintf (stderr, "error: insufficient input.\n"
"usage: %s <file> <searchstring>\n", argv[0]);
return 1;
}
/* search file argv[1] for string argv[2] */
if (searchinfile (argv[1], argv[2]))
fprintf (stderr, "unable to search '%s'.\n", argv[1]);
return 0;
}
示例输入文件
$ cat dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
例子Use/Output
$ /tmp/tmp-david/greplite dat/captnjack.txt Sea
[dat/captnjack.txt:4] On the Seven Seas.
请注意代码中的注释——传递一个附加参数以指示是否应执行 case-insensitive 搜索(然后在搜索之前将行和 search-term 转换为 lower-case)。
检查一下,如果您还有其他问题,请告诉我。