C 字符数组串联内存转储
C char array concatenation memory dumped
我有以下代码:
char * set_number(void)
{
// char * sname = malloc(sizeof(char) * 18); Original
char * sname = malloc(sizeof(char) * 19); // After EDIT 1
memset(sname, '[=10=]', 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;
}
returns :
str : 12345678912345
正如评论中所写,我想将 c
连接成 wnumber
。
但是,使用 strcat()
会导致内存转储。
此外,内存需要释放到主函数中,不是吗?
我想我还是误解了这里的逻辑。
在我看来,问题是
malloc()
不会 return 空初始化的内存块并且 strcat()
期望第一个参数是空终止的。
- 如果要将数组用作 string.
,还需要为空终止符分配内存
所以,
- 在为
sname
. 分配内存时,分配 space 用于保存空终止符
- 使用
strcpy()
将字符串复制到sname
。否则,如果你想继续使用strcat()
,你可以调用calloc()
其中return的0填充内存。
- 您只能在 return 由
malloc()
和家人编辑的原始指针上调用 free()
。如果您打算移动实际指针,则需要在某处保留原始指针的副本,以便稍后传递给 free()
。
如果您的字符串以 0x00
开头,您希望删除该前缀并附加一个 7。你的方法有几个问题,其中许多问题已经被其他人解决了:
- 您必须保留从
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 [=10=]
| |
+-------+ +-------+
| |
after 1 2 3 4 5 6 7 8 9 1 2 3 4 5 7 [=10=]
| |
+--+---- 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++] = '[=11=]'; // 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;
}
我有以下代码:
char * set_number(void)
{
// char * sname = malloc(sizeof(char) * 18); Original
char * sname = malloc(sizeof(char) * 19); // After EDIT 1
memset(sname, '[=10=]', 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;
}
returns :
str : 12345678912345
正如评论中所写,我想将 c
连接成 wnumber
。
但是,使用 strcat()
会导致内存转储。
此外,内存需要释放到主函数中,不是吗?
我想我还是误解了这里的逻辑。
在我看来,问题是
malloc()
不会 return 空初始化的内存块并且strcat()
期望第一个参数是空终止的。- 如果要将数组用作 string. ,还需要为空终止符分配内存
所以,
- 在为
sname
. 分配内存时,分配 space 用于保存空终止符
- 使用
strcpy()
将字符串复制到sname
。否则,如果你想继续使用strcat()
,你可以调用calloc()
其中return的0填充内存。 - 您只能在 return 由
malloc()
和家人编辑的原始指针上调用free()
。如果您打算移动实际指针,则需要在某处保留原始指针的副本,以便稍后传递给free()
。
如果您的字符串以 0x00
开头,您希望删除该前缀并附加一个 7。你的方法有几个问题,其中许多问题已经被其他人解决了:
- 您必须保留从
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 [=10=]
| |
+-------+ +-------+
| |
after 1 2 3 4 5 6 7 8 9 1 2 3 4 5 7 [=10=]
| |
+--+---- 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++] = '[=11=]'; // 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;
}