我有以下代码:
char * set_number(void)
{
// char * sname = malloc(sizeof(char) * 18); Original
char * sname = malloc(sizeof(char) * 19); // After EDIT 1
memset(sname, '\0', 19); // After EDIT 1
strcat(sname, "0x0012345678912345");
return sname;
}
char * get_number(void)
{
char * rnumber = set_number();
return rnumber;
}
char * work_with_number(void)
{
int i = 7;
char * wnumber = get_number();
if(strstr(wnumber, "0x00") != NULL)
{
wnumber += 4;
char c = i + '0';
// Would like to concatene c at the end of wnumber here
}
return wnumber;
}
int main(int argc, char **argv)
{
char * str = work_with_number();
fprintf(stdout, "str : %s\n", str);
return 0;
}
返回:
str : 12345678912345
正如在评论中写的那样,我想将c
连接到wnumber
。
但是,使用strcat()
会产生内存转储。
另外内存需要释放到主函数中,不是吗?
我想我仍然误解了这里的逻辑。
答案 0 :(得分:4)
我认为这个问题是
malloc()
不返回空初始化的内存块,strcat()
期望第一个参数为空终止。所以,
sname
分配内存时分配用于保留空终止符的空间。strcpy()
将字符串复制到sname
。否则,如果要继续使用calloc()
,可以调用strcat()
返回0填充的内存。free()
和家人返回的原始指针上调用malloc()
。如果您打算移动实际指针,则需要将原始指针的副本保存在稍后传递给free()
的位置。答案 1 :(得分:2)
如果您的字符串以0x00
开头,则您要删除该前缀并添加七个字符串。您的方法存在一些问题,其中许多问题已由其他人解决:
malloc
收到的指针,以便稍后free
内存。strstr
在字符串中的任意位置查找搜索字符串,但您想测试0x00
是否在开头。请使用strncmp
。strcat
连接到以零结尾的字符串,但先将内存归零然后strcat
ting是浪费的。直接strcpy
到字符串。另一种方法是将字符串的其余部分移到前面。这将留下最后四个字符,您可以使用它来附加内容,但当然不会超过您删除的内容:
before: 0 x 0 0 1 2 3 4 5 6 7 8 9 1 2 3 4 5 \0
| |
+-------+ +-------+
| |
after 1 2 3 4 5 6 7 8 9 1 2 3 4 5 7 \0
| |
+--+---- new
你可以为此编写一个循环,但标准库中还有两个函数:memcpy
,它要求缓冲区不重叠,memmove
,它可以处理重叠缓冲区。您需要memmove
。
所以:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char *get_number(void)
{
char *sname = malloc(19);
if (sname) strcpy(sname, "0x0012345678912345");
return sname;
}
char *work_with_number(void)
{
char *wnumber = get_number();
if(strncmp(wnumber, "0x00", 4) == 0) {
size_t len = strlen(wnumber + 4); // length of rest of str
memmove(wnumber, wnumber + 4, len); // move rest to front
wnumber[len++] = '7'; // append digit seven
wnumber[len++] = '\0'; // append null terminator!
}
return wnumber;
}
int main(int argc, char **argv)
{
char *str = work_with_number();
fprintf(stdout, "str : %s\n", str); // user str
free(str); // free it after use
return 0;
}