从函数返回char*
Return char* from function
下面是3个函数。Main()按预期输出。现在,在mycharstack()中,字符串被存储在堆栈上,我猜,所以当"ch"超出范围时,它应该不能返回字符串。它是如何正确工作的?我猜存储在mychar()中的字符串也在堆栈上。它应该能正常工作吗?我猜还有其他错误的代码和内存泄漏,请让我知道如果有任何。我可以做得更干净一些;使用std::string更容易。但是我想知道char*.
是怎么回事#include <iostream>
using namespace std;
char* mychar()
{
return "Hello";
}
char* mycharstack()
{
char* ch = "Hello Stack";
return ch;
}
char* mycharheap()
{
char* ch = new char;
ch = "Hello Heap";
return ch;
}
int main()
{
cout << "mychar() = " << mychar() << endl;
cout << "mycharstack() = " << mycharstack() << endl;
cout << "mycharheap() = " << mycharheap() << endl;
system("PAUSE");
return 0;
}
在c++中,字符串处理不同于pascal。
char* mycharheap()
{
char* ch = new char;
ch = "Hello Heap";
return ch;
}
-
char* ch = new char;
为一个字符创建内存,并将其分配给变量ch
-
ch = "Hello Heap";
赋给变量ch
一个指针到只读内存,该只读内存包含字节"Hello Heap "
。另外,变量ch
的原始内容丢失,导致内存泄漏。 -
return ch;
返回指向变量ch
的指针。
你可能想要的是
char* mycharheap()
{
char* ch = new char[11] /* 11 = len of Hello Heap + 1 char for */;
strcpy(ch, "Hello Heap");
return ch;
}
注意strcpy
->你在ch
中有内存,有11个字符的空间,并且你正在从内存的只读部分用字符串填充它。
在这种情况下会有泄漏。您需要在写入后删除内存,如:
char* tempFromHeap = mycharheap();
cout << "mycharheap() = " << tempFromHeap << endl;
delete[] tempFromHeap;
然而,我强烈建议不这样做(在callee中分配内存,在caller中删除内存)。对于这种情况,有,例如,STL std::string
,另一种常见且更合理的方法是在调用者中分配,传递给被调用者,它用结果"填充"内存,然后再次在调用者中释放。
导致未定义行为的条件如下:
char* mycharstack()
{
char[] ch = "Hello Heap"; /* this is a shortcut for char[11] ch; ch[0] = 'H', ch[1] = 'e', ...... */
return ch;
}
这将在堆栈上创建具有"Hello Heap "
字节的数组,然后尝试返回指向该数组第一个字节的指针(在调用函数时,该指针可以指向任何值)
在mycharstack()中的字符串存储在堆栈上,我猜,所以当"ch"超出范围时,它不应该能够返回字符串。它是如何正确工作的?
字符串字面值指向位于静态内存中的数组。我希望你知道三个内存区域:自动内存(又名堆栈),自由存储(又名堆)和静态内存。堆栈上的那个东西只是一个指针变量,你按值返回指针的值(它存储的地址)。所以一切都很好,除了你应该使用const char*
作为指针类型,因为你不允许修改字符串字面量引用的数组。
我猜存储在mychar()中的字符串也在堆栈上。
字符串(字符数组)存储在静态内存中。char*
只是一个指针类型,你可以用它来传递地址。const
也不见了
我猜代码中还有其他错误和内存泄漏,如果有的话请告诉我。
泄漏在第三个函数中。您只需为堆上的一个字符分配内存,并将其地址存储到名为ch
的变量中。使用下面的赋值操作,可以用字符串字面值的地址覆盖此地址。所以,你在泄漏内存。
你似乎认为char*
是字符串变量的类型。但事实并非如此。它是指向字符或字符序列的指针的类型。指针和它可能指向的字符串是两个独立的东西。这里应该使用std::string
首先,如果您使用c++,请使用std::string
来表示字符串。
char*
是指向char
(或char
s的数组)的指针。字符串字面值(引号中的东西)是char
数组类型的只读对象,存储在某种只读内存中(既不是堆栈也不是堆)。
由于char*
是指针,对其赋值会改变指针。因此,mychar()
和mycharstack()
都返回一个指针,指向存储在只读内存中的字符串字面值。
mycharheap()
只是泄漏。您使用new char
在堆上分配一个char
,然后忘记它的地址,而是返回一个指向字符串字面值的指针。我猜你是这个意思:
char* mycharheap() {
char* ch = new char[strlen("Hello Heap") + 1];
strcpy(ch, "Hello Heap");
return ch;
}
然而,重申一下,不要在c++中对字符串使用char*
。使用std::string
函数mycharheap()
正在泄漏:您使指针指向在堆上分配的一个char
长度的内存区域,然后您修改该指针指向存储在只读内存中的字符串文字。已分配的内存不会被释放
您的代码中没有错误,只是泄露了char
。但这很奇怪。
char* mycharheap()
{
char* ch = new char; //creates a pointer that points to a new char in the heap
ch = "Hello Heap"; //overwrites the pointer with const char - but this cast is legal.
//note: pointer to the previous char is lost
return ch; //return the pointer to the constant area where "Hello heap" is stored.
//no, "Hello heap" is not on the heap.
}
在"What you want:"部分,尤塞连比我快。
下面的例子是当我试图从函数调用中提取信息时出现的一个问题。
#include <iostream>
#include <cstring>
using namespace std;
char* Xout(char* message);
int main()
{
const int LEN = 64;
char message[LEN], *x;
cin>>message;
x=Xout(message);
cout<<x;
return 0;
}
char* Xout(char* message)
{
int length=strlen(message);
for(int i = 0; i < length; i++)
{
message[i] = 'X';
}
return message;
}
const char* mychar_readonly() {
// each time it returns the same pointer to char array in Read-Only memory
return "Hello Read-Only";
}
int main() {
const char* s1 = mychar_readonly();
const char* s2 = mychar_readonly();
// it will print the same addresses
// e.g s1: 0x100000f87, s2: 0x100000f87
printf("s1: %p, s2: %pn", s1, s2);
return 0;
}
- 为什么 Serial.println(<char[]>);返回随机字符?
- 从函数返回const char*数组
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- 将传入的网络"char*"数据转换为"uint8_t"并返回的安全方法是什么?
- 使用 map<char,strring> 的迭代器返回指针 map<char,strring>*
- 错误:为"运算符 std::string {aka std::__cxx11::basic_string}"指定的返回类型<char>
- C++函数返回两个 char 数组的相同索引元素
- 为什么 char 数组在从 C++ 中的函数返回时会丢失?
- 为什么类型 char 返回不同的值?
- 内存浪费?如果main()应该只返回0或1,那么为什么main是用int而不是短int甚至char声明的
- 从内部使用静态 std::string 的函数返回 const char * 是否安全?
- 从类方法返回 "const char*" 作为 std::string&
- 使用 ctypes 从函数返回字符串C++会给出大的 int,而不是 char 指针
- boost::hash/std::tr1::hash 不为复制的 const char* 返回相同的哈希
- 具有返回值 char* 返回垃圾的函数
- C++动态内存分配.将动态分配的 char* 返回变量数组分配给 char 变量
- Char 返回奇怪的输出C++
- 使用reinterpret_cast从char*返回long long
- try-catch对char**返回值有影响