C中是正确的吗?
char *func1() {
char *str[3] = { "so", "is", "amazing" };
return str[1];
}
char *func1()
返回一个指针,指向内存中存储字符串的位置。但是当func1()
返回时,str
数组不会超出范围,我不是返回指向不存在对象的指针吗?悬空的指针(这是正确的名称吗?
所以我有两个解决方案使str
全局的,这样它就不会超出范围,指针总是指向一个有效的内存地址,但这似乎很脏。
其他解决方案
char *func2() {
char *str[3] = { "so", "is", "amazing" };
int str1Len = strlen(str[1]);
char *ret = (char *)malloc(str1Len) ; // create a block of mem to hold the str[1].
strncpy(ret, str[1], str1Len);
return ret;
}
这是对的吗?func1()
或func2()
的正确方法是什么?还是有更好的方法?
我已经使用func1()
一段时间了,它没有给我带来任何问题,这是否意味着func1()
在做正确的事情? func2()
是不必要的?
在你的第一个函数中,返回str[1]
没有问题,因为它不指向局部变量,它是一个指向字符串文字的指针。 请注意,字符串文字应声明const
:
const char *func1(void) {
const char *str[3] = { "so", "is", "amazing" };
return str[1];
}
第二个函数返回指向已分配空间的指针。 此指针需要在某个时候释放。 分配不正确,您应该为最终' '
分配 1 个额外的字节。 您可以使用strcpy
将字符串复制到分配的空间,或者仅使用同时执行这两项操作的strdup()
:
char *func2(void) {
const char *str[3] = { "so", "is", "amazing" };
int size = strlen(str[1]) + 1;
char *ret = malloc(size);
return strcpy(ret, str[1]);
}
或者简单地说:
char *func2(void) {
const char *str[3] = { "so", "is", "amazing" };
return strdup(str[1]);
}
永远不要使用strncpy
,它不会做你认为它做的事情。对于程序员和任何将要阅读您的代码的人来说,它都非常容易出错。
-
这在 C 中是正确的做法吗?
不,不是!您通常需要创建局部变量的副本,尽管在这种情况下,指针指向字符串文本,以便它可以工作。
-
您分配和复制了错误的字符串,您应该这样做
size_t size = strlen(str[1]) + 1; char *result = malloc(size) ; // create a block of mem to hold the str[1]. if (result != NULL) memcpy(ret, str[1], size);
指针返回到字符串文字是可以接受的,但不是本地指针,这可能是错误的方法。
如果str
没有更改,请将其设为static const char * const str[] = ....
这限定了数组和它指向 const 的char []
(每个字符串文字)。static
使它永久化,但仍具有本地范围。它在程序代码启动之前设置一次。相比之下,非static
版本将为每个调用设置数组。
请注意,您必须返回一个const char *
以保持恒定正确性。我强烈建议这样做;如果不能,请仅省略第一个const
。
注意:不要在 C 中投射 malloc
& friends(或一般void *
)的结果。