每当我遇到处理c字符串的情况时,我都很困惑。
为什么这两个印刷品有相同的结果? 在我的理解中,第一个函数在文本变量中指定字符串的地址。这似乎对我来说很合适。但第二个函数指定文本变量指向的地址。这里发生了什么?
#include <iostream>
#include <cstring>
void getText(char** text) {
*text = strdup("AAAAA");
}
void getText2(char* text) {
text = strdup("AAAAA");
}
int main()
{
char* text;
getText(&text);
std::cout << text << std::endl; // prints "AAAAA"
getText2(text);
std::cout << text << std::endl; // prints "AAAAA"
}
答案 0 :(得分:1)
在第一种情况下,您传递了指向本地指针的指针,您取消引用该指针并使其指向strdup()
返回的值,您正在修改原始指针指向的地址。
在第二个中,你传递poiner本身,你不能在函数内部改变它,因为即使两个指针最初指向同一个内存,它们也存储在不同的地方,所以改变一个地址不会。 ; t影响对方。
如果您更改指针指向的数据,而不是getText2()
中的地址,那么它将会改变,例如
text[0] = 'B';
text[1] = 'B';
text[2] = 'B';
text[3] = 'B';
text[4] = 'B';
使用free()
返回的指针后,您还应该调用strdup()
,否则将导致内存泄漏。
最后,使用c ++中的指针目前被认为是不好的做法,除非你是一个图书馆程序员,我不认为是这样。相反,使用std::string
和所有c ++概念(类似于c 中不存在的引用传递),这将允许您编写现代c ++程序。
可以通过c ++中的引用传递
void getText(std::string &text)
{
text = "AAAAAA";
}
void getText2(std::string &text)
{
text = "BBBBBB";
}
int main()
{
std::string text;
getText(text);
std::cout << text << std::endl;
getText2(text);
std::cout << text << std::endl;
return 0;
}
你去,没有内存泄漏,它按预期工作,它是现代的c ++。
答案 1 :(得分:1)
此功能
void getText2(char* text) {
text = strdup("AAAAA");
}
内存泄漏。
函数参数是函数局部变量。
您可以想象函数getText2的定义及其调用方式如下。我重命名了函数参数,它会更清楚。
getText2(text);
//...
void getText2( /*char* parm_text */) {
char *parm_text = text;
parm_text = strdup("AAAAA");
}
退出函数后,将销毁参数parm_text
的局部变量。但是在本声明中分配了内存
parm_text = strdup("AAAAA");
未被释放。
另一方面,论证本身没有改变。该函数使用存储在分配给局部变量的参数中的值。
您可以将参数声明为参数的引用。例如
void getText2(char* &text) {
^^^^^
text = strdup("AAAAA");
}
在这种情况下,参数本身在函数中被更改。
关于功能
void getText(char** text) {
*text = strdup("AAAAA");
}
然后通过使用指向参数的指针间接传递参数。因此,在函数内部,参数的值会发生变化。