假设我要根据给定的字符串(作为对函数的参数)创建新字符串并返回新字符串。
在main中调用该方法时,永远不会创建新的字符串,而且我也不明白为什么。
这是我在main之外的函数中的代码:
char* new_name(char* name)
{
char* res = (char*)malloc(strlen("recv") + strlen(name));
if(res == null)
{
return null;
}
else
{
memcpy(&res, "recv_", strlen("recv_"));
strcat(res, name);
}
return res;
}
主要我有:
char * result = new_name(name);
定义并给出“名称”的地方。
答案 0 :(得分:1)
在
char* res = (char*)malloc(strlen("recv") + strlen(name));
由于后面的代码,您需要分配“ recv_”而不是“ recv”,并为终止的空字符再分配1个空间,因此
char* res = (char*)malloc(strlen("recv_") + strlen(name) + 1);
在
if(res == null) { return null; }
null 必须为 NULL
在
memcpy(&res, "recv_", strlen("recv_"));
必须
memcpy(res, "recv_", strlen("recv_") + 1);
否则,您将不会修改分配的数组,而是修改变量 res 的地址中的堆栈,还需要放置终止的空字符,因此我只需将1的char数加到复制
请注意,使用 strcpy 更为简单:strcpy(res, "recv_")
示例:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* new_name(char* name)
{
char* res = (char*)malloc(strlen("recv_") + strlen(name) + 1);
if(res == NULL)
{
return NULL;
}
else
{
memcpy(res, "recv_", strlen("recv_") + 1); /* or strcpy(res, "recv_"); */
strcat(res, name);
}
return res;
}
int main()
{
char * result = new_name("foo");
printf("'%s'\n", result);
free(result);
return 0;
}
编译和执行:
pi@raspberrypi:~ $ gcc -pedantic -Wall -Wextra m.c
pi@raspberrypi:~ $ ./a.out
'recv_foo'
在 valgrind 下执行:
pi@raspberrypi:~ $ valgrind ./a.out
==22335== Memcheck, a memory error detector
==22335== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==22335== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==22335== Command: ./a.out
==22335==
'recv_foo'
==22335==
==22335== HEAP SUMMARY:
==22335== in use at exit: 0 bytes in 0 blocks
==22335== total heap usage: 2 allocs, 2 frees, 1,033 bytes allocated
==22335==
==22335== All heap blocks were freed -- no leaks are possible
==22335==
==22335== For counts of detected and suppressed errors, rerun with: -v
==22335== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
答案 1 :(得分:1)
一种替代解决方案可以是:
#include <stdio.h>
#include <stdlib.h>
char *new_name(char *name) {
char const prefix[] = "recv_";
// Figure out size needed
int sz = snprintf(NULL, 0, "%s%s", prefix, name);
sz++; // make room for '\0' at end
char *res = malloc(sz);
if (res == NULL) {
return NULL;
}
(void) snprintf(res, sz, "%s%s", prefix, name);
return res;
}
或者,为避免多次计算name
的长度,
char* new_name(char* name)
{
char const prefix[] = "recv_";
size_t const pre_len = sizeof prefix - 1U;
size_t const name_len = strlen(name) + 1U;
char* res = (char*)malloc(pre_len + name_len);
if(res)
{
memcpy(res, prefix, pre_len);
memcpy(res + pre_len, name, name_len);
}
return res;
}