由于我保证存在的原因,我正逐字符地读取输入,如果一个字符满足某些条件,我就把它写入一个动态分配的缓冲区。此函数将指定的字符添加到指定字符串的“end”。当读出缓冲区时,我会读取第一个“大小”字符。
void append(char c, char *str, int size)
{
if(size + 1 > strlen(str))
str = (char*)realloc(str,sizeof(char)*(size + 1));
str[size] = c;
}
这个功能,通过各种迭代的开发产生了诸如“损坏的双链表”,“双重自由或腐败”之类的错误。下面是一个如何使用append的示例:
// buffer is a string
// bufSize is the number of non-garbage characters at the beginning of buffer
char *buft = buffer;
int bufLoc=0;
while((buft-buffer)/sizeof(char) < bufSize)
append(*(buft==),destination,bufLoc++);
它通常适用于一些看似任意数量的字符,然后中止错误。如果不清楚第二个代码片段在做什么,它只是从缓冲区复制到某个目标字符串。我知道有这样的库方法,但我需要更精确地控制有时复制的内容。
提前感谢任何见解。我很难过。
答案 0 :(得分:4)
此函数不会将字符附加到缓冲区。
void append(char c, char *str, int size)
{
if(size + 1 > strlen(str))
str = realloc(str, size + 1);
str[size] = c;
}
首先,strlen(str)
是什么?你可以说“它是str
的长度”,但这省略了一些非常重要的细节。它如何计算长度?简单 - str
必须以NUL终止,并且strlen
找到其中第一个NUL
字节的偏移量。如果您的缓冲区末尾没有NUL字节,则无法使用strlen
来查找其长度。
通常,您需要跟踪缓冲区的长度。为了减少重新分配的数量,请分别跟踪缓冲区大小和数据量。
struct buf {
char *buf;
size_t buflen;
size_t bufalloc;
};
void buf_init(struct buf *b)
{
buf->buf = NULL;
buf->buflen = 0;
buf->bufalloc = 0;
}
void buf_append(struct buf *b, int c)
{
if (buf->buflen >= buf->bufalloc) {
size_t newalloc = buf->bufalloc ? buf->bufalloc * 2 : 16;
char *newbuf = realloc(buf->buf, newalloc);
if (!newbuf)
abort();
buf->buf = newbuf;
buf->bufalloc = newalloc;
}
buf->buf[buf->buflen++] = c;
}
此代码:
str = realloc(str, size + 1);
它只会更改str
中append
的值 - 它不会更改调用函数中str
的值。函数参数是函数的本地参数,更改函数参数不会影响函数之外的任何内容。
这有点奇怪:
// Weird
x = (char*)realloc(str,sizeof(char)*(size + 1));
(char *)
强制转换不仅是不必要的,而且它实际上可以掩盖错误 - 如果您忘记包含<stdlib.h>
,则强制转换将允许代码进行编译。长号。
根据定义,sizeof(char)
为1。所以不要打扰。
// Fixed
x = realloc(str, size + 1);
答案 1 :(得分:0)
当你这样做时:
str = (char*)realloc(str,sizeof(char)*(size + 1));
str中的更改不会反映在调用函数中,换句话说,当指针通过值传递时,更改是函数的本地更改。要解决此问题,您可以返回str:
的值char * append(char c, char *str, int size)
{
if(size + 1 > strlen(str))
str = (char*)realloc(str,sizeof(char)*(size + 1));
str[size] = c;
return str;
}
或者您可以通过地址传递指针:
void append(char c, char **str, int size)
{
if(size + 1 > strlen(str))
*str = (char*)realloc(*str,sizeof(char)*(size + 1));
(*str)[size] = c;
}