动态内存分配 +截断字符串问题
为了编写一些基本函数来操作 C 字符串(char*),我一直在使用 malloc、realloc 和 free。从字符串中删除最后一个字符时,我遇到了这个奇怪的问题。我写了一个具有这样原型的函数:
int string_erase_end (char ** dst, size_t size);
它应该将“dst”字符串缩短一个字符。到目前为止,我已经想出了这段代码:
int string_erase_end (char ** dst, size_t size)
{
size_t s = strlen(*dst) - size;
char * tmp = NULL;
if (s < 0) return (-1);
if (size == 0) return 0;
tmp = (char*)malloc(s);
if (tmp == NULL) return (-1);
strncpy(tmp,*dst,s);
free(*dst);
*dst = (char*)malloc(s+1);
if (*dst == NULL) return (-1);
strncpy(*dst,tmp,s);
*dst[s] = '\0';
free(tmp);
return 0;
}
在 main() 中,当我截断字符串时(是的,我之前对它们调用了 malloc),我得到了奇怪的结果。根据我想要截断的字符数,它要么工作正常,要么截断错误数量的字符,要么引发分段错误。
我没有动态内存分配的经验,一直使用 C++ 及其 std::string 来完成所有这些肮脏的工作,但这次我需要在 C 中完成这项工作。如果有人帮助我找到并纠正我的问题,我将不胜感激。这里有错误。提前致谢。
I've been fooling around with malloc, realloc and free in order to write some basic functions to operate on C strings (char*). I've encountered this weird issue when erasing the last character from a string. I wrote a function with such a prototype:
int string_erase_end (char ** dst, size_t size);
It's supposed to shorten the "dst" string by one character. So far I have come up with this code:
int string_erase_end (char ** dst, size_t size)
{
size_t s = strlen(*dst) - size;
char * tmp = NULL;
if (s < 0) return (-1);
if (size == 0) return 0;
tmp = (char*)malloc(s);
if (tmp == NULL) return (-1);
strncpy(tmp,*dst,s);
free(*dst);
*dst = (char*)malloc(s+1);
if (*dst == NULL) return (-1);
strncpy(*dst,tmp,s);
*dst[s] = '\0';
free(tmp);
return 0;
}
In main(), when I truncate strings (yes, I called malloc on them previously), I get strange results. Depending on the number of characters I want to truncate, it either works OK, truncates a wrong number of characters or throws a segmentation fault.
I have no experience with dynamic memory allocation and have always used C++ and its std::string to do all such dirty work, but this time I need to make this work in C. I'd appreciate if someone helped me locate and correct my mistake(s) here. Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
第一个 strncpy() 不会在 tmp 末尾放置 '\0'。
另外,您可以避免重复复制: *dst = tmp;
The first strncpy() doesn't put a '\0' at the end of tmp.
Also, you could avoid a double copy: *dst = tmp;
根据您的描述,您的函数应该删除字符串中的最后 n 个字符:
According to your description your function is supposed to erase the last n characters in a string:
我不明白
size
参数的用途。如果您的字符串最初是使用
malloc()
分配的,那么您应该只使用realloc()
来更改它们的大小。这将自动保留内容,并且需要更少的操作:在“现实世界”中,您通常不会更改 1 字符截断的分配大小;效率太低了。相反,您可以分别跟踪字符串的长度及其分配的大小。这使得弦更容易生长;只要已经分配了空间,追加字符就非常快。
此外,在 C 中,您永远不需要转换
malloc()
的返回值;它没有任何作用并且可以隐藏错误,所以不要这样做。I don't understand the purpose of the
size
parameter.If your strings are initially allocated using
malloc()
, you should just userealloc()
to change their size. That will retain the content automatically, and require fewer operations:In the "real world", you would generally not change the allocated size for a 1-char truncation; it's too inefficient. You would instead keep track of the string's length and its allocated size separately. That makes it easy for strings to grow; as long as there is allocated space already, it's very fast to append a character.
Also, in C you never need to cast the return value of
malloc()
; it serves no purpose and can hide bugs so don't do it.