平台:Windows Vista Home Premium SP2 x86
编译器:MinGW(GCC 4.7.1 tdm-1)(IDE:Code :: Blocks)
我正在编写一个使用相当常见的垃圾收集器循环的函数(getc(stdin)!='\ n')来编写一个动态获取字符串函数,该函数将读取fgets()在标准输入中留下的任何数据呼叫。我正在Windows上编写这个函数,因为我目前无法访问我的电脑,只是为了让你们知道。但我的问题是我希望我的函数dgets()到malloc()一个缓冲区,如果给它的指针是NULL但同时我希望函数返回一个整数。所以我对这个问题的解决方案是一个指向char指针的指针。该函数将被调用。
char *s = NULL;
int n = 0;
if(dgets(&s, &n) != 0) //ERROR
我不经常使用指针指针,所以当我的函数崩溃时我有点困惑。我通过使用以下循环将问题缩小到我解除引用的方式。
char* *s;
int i = 0;
*s = malloc(32);
for(; i < 32; i++) printf("*s[%i] == %c\n", i, *s[i]);
编译并运行上面的代码时,它会崩溃。我的问题是为什么?这是上下文的功能。附:它尚未经过测试,但任何评论都会受到赞赏。
#include <windows.h>
#include <stdio.h>
#include <errno.h>
int dgets(char* *s, size_t *n)
{
if(n == NULL) return 1;
if(*n < 0) return 1;
if(*n == 0) *n = 32;
if(s == NULL) return 1;
if(*s == NULL && (*s = malloc(*n)) == NULL) return 1;
int i = 0;
for(; i <= *n; i++) *s[i] = 0;
if(fgets(*s, *n, stdin) == NULL) return 1;
//Since fgets() will put newlines in the buffer, input is line buffered,
//and the buffer was initilized to zero if the last element
//is a nonzero value and not a newline then there must be a newline left
//in stdin.
if(*s[*n - 1] != 0 && *s[*n - 1] != '\n')
{
i = *n;
int byte = 0;
char *tmp = NULL;
for(; (byte = getc(stdin)) != '\n'; i++)
{
if(byte == EOF) return 1;
if(i == *n)
{
//eventually an arbitrary limit will be put here to limit the
//size of the buffer
*n *= 2;
if((tmp = realloc(*s, *n)) == NULL) return 1;
*s = tmp;
}
*s[i] = (char)byte;
}
//reallocates the buffer so that it is exact size
if(*n != i + 2 && (tmp = realloc(*s, i + 2)) == NULL) return 1;
*s = tmp;
*n = i + 2;
*s[i] = (char)byte;
*s[i + 1] = 0;
}
return 0;
}
答案 0 :(得分:1)
我注意到的两个问题。
类型不匹配
int n;
if(dgets(&s, &n) != 0)
dgets 原型是 int dgets(char ** s,size_t * n)
&amp; n: int * ,但需要 size_t *
超出范围的阵列访问&amp;解除引用错误
for(; i <= *n; i++) *s[i] = 0;
它可以访问保留的外部存储器。
应该是 i&lt; * n 和(* s)[i] = 0;
*s[i]
表示*(s[i])
还需要根据上述更改更改程序的其余部分。