C++ 从函数返回 char*
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14379328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Return char* from function
提问by ontherocks
Below are 3 functions. main() prints out as expected. Now, in mycharstack() the string is stored on stack I guess, so as "ch" goes out of scope, it should not be able to return the string. How does it work correctly? I guess the string stored in mychar() is also on stack. Is it supposed to work correctly? I guess there are other errors in the code and memory leaks, please let me know if any. I could do these cleaner & easier with std::string. But I want to understand what's going on with char*.
下面是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;
}
采纳答案by nothrow
In C++, the string handling is different from, for example, pascal.
在 C++ 中,字符串处理不同于例如 pascal。
char* mycharheap()
{
char* ch = new char;
ch = "Hello Heap";
return ch;
}
This does following:
这执行以下操作:
char* ch = new char;
creates memory for ONE character, and assigns it to variablech
ch = "Hello Heap";
assigns to variablech
pointer to readonly memory, which contains bytes"Hello Heap\0"
. Also, the original content of variablech
is lost, resulting in memory leak.return ch;
returns the pointer stored to variablech
.
char* ch = new char;
为一个字符创建内存,并将其分配给变量ch
ch = "Hello Heap";
分配给ch
只读内存的变量指针,其中包含 bytes"Hello Heap\0"
。另外,变量的原始内容ch
丢失,导致内存泄漏。return ch;
返回存储到变量的指针ch
。
What you probably wanted is
你可能想要的是
char* mycharheap()
{
char* ch = new char[11] /* 11 = len of Hello Heap + 1 char for char* tempFromHeap = mycharheap();
cout << "mycharheap() = " << tempFromHeap << endl;
delete[] tempFromHeap;
*/;
strcpy(ch, "Hello Heap");
return ch;
}
Note the strcpy
-> you've got memory in ch
, that has space for 11 chars, and you are filling it by string from read-only portion of memory.
注意strcpy
-> 你有内存ch
,它有 11 个字符的空间,你正在用内存的只读部分的字符串填充它。
There will be a leak in this case. You will need to delete the memory after writing, like:
在这种情况下会有泄漏。写入后您需要删除内存,例如:
char* mycharstack()
{
char[] ch = "Hello Heap"; /* this is a shortcut for char[11] ch; ch[0] = 'H', ch[1] = 'e', ...... */
return ch;
}
However, I highlydon't recommend doing this (allocating memory in callee and deleting in caller). For this situations, there are, for example, STL std::string
, another common and more reasonable approach is allocating in caller, passing to callee, which 'fills' the memory with result, and deallocating in caller again.
但是,我强烈不建议这样做(在被调用者中分配内存并在调用者中删除)。对于这种情况,例如 STL std::string
,另一种常见且更合理的方法是在调用者中分配,传递给被调用者,用结果“填充”内存,然后再次在调用者中释放。
What will result in undefined behavior is following:
将导致未定义行为的原因如下:
char* mycharheap() {
char* ch = new char[strlen("Hello Heap") + 1];
strcpy(ch, "Hello Heap");
return ch;
}
This will create array on stack with bytes "Hello Heap\0"
, and then tries to return pointer to first byte of that array (which can, in calling function, point to anything)
这将使用 bytes 在堆栈上创建数组"Hello Heap\0"
,然后尝试返回指向该数组第一个字节的指针(在调用函数中,它可以指向任何内容)
回答by sellibitze
in mycharstack() the string is stored on stack I guess, so as "ch" goes out of scope, it should not be able to return the string. How does it work correctly?
在 mycharstack() 中,我猜字符串存储在堆栈中,因此当“ch”超出范围时,它应该无法返回字符串。它是如何正确工作的?
A string literal refers to an array that lives in staticmemory. I hope you are aware of the three memory areas: automatic memory (aka stack), free store (aka heap) and static memory. That thing on the stack is just a pointer variable and you return the value of the pointer (the address it stores) by value. So everything is fine except for the fact that you should have used const char*
as pointer type because you are not allowed to modify the array a string literal refers to.
字符串字面量是指存在于静态内存中的数组。我希望你知道三个内存区域:自动内存(又名堆栈)、自由存储(又名堆)和静态内存。堆栈上的那个东西只是一个指针变量,你按值返回指针的值(它存储的地址)。所以一切都很好,除了您应该用作const char*
指针类型的事实,因为您不允许修改字符串文字所指的数组。
I guess the string stored in mychar() is also on stack.
我猜存储在 mychar() 中的字符串也在堆栈中。
The string (the character array) is stored in static memory. char*
is just a pointer type you can use to pass addresses around. const
is also missing.
字符串(字符数组)存储在静态内存中。char*
只是一种可以用来传递地址的指针类型。const
也不见了。
I guess there are other errors in the code and memory leaks, please let me know if any.
我猜代码中还有其他错误和内存泄漏,如果有的话请告诉我。
The leak is in your third function. You allocate memory for just one character on the heap and store its address into the variable called ch
. With the following assignment you overwrite this address with the address of a string literal. So, you're leaking memory.
泄漏在您的第三个功能中。您只为堆上的一个字符分配内存,并将其地址存储到名为 的变量中ch
。通过以下分配,您可以使用字符串文字的地址覆盖此地址。所以,你正在泄漏内存。
You seem to be thinking of char*
as type for string variables. But it is not. It's the type for a pointer to a character or character sequence. The pointer and the string it might point to are two seperate things. What you probably should be using here is std::string instead.
您似乎正在考虑char*
作为字符串变量的类型。但事实并非如此。它是指向字符或字符序列的指针的类型。指针和它可能指向的字符串是两个独立的东西。您可能应该在这里使用的是 std::string 。
回答by Angew is no longer proud of SO
First off, if you're using C++, use std::string
to represent strings.
首先,如果您使用的是 C++,请使用std::string
来表示字符串。
Now to your question. char*
is a pointer to char
(or array of char
s). String literals (stuff in quotes) are read-only objects of type array of char
, stored in some sort of read-only memory (neither on stack or heap).
现在回答你的问题。char*
是指向char
(或char
s数组)的指针。字符串文字(引号中的内容)是数组类型的只读对象char
,存储在某种只读内存中(不在堆栈或堆上)。
As char*
is a pointer, assigning into it changes the pointer. So mychar()
and mycharstack()
both return a pointer to a string literal stored in read-only memory.
与char*
指针一样,分配给它会改变指针。因此mychar()
,mycharstack()
两者都返回一个指向存储在只读存储器中的字符串文字的指针。
mycharheap()
simply leaks. You allocate one char
on the heap using new char
, and then forget its address and return a pointer to a string literal instead. I guess you meant this:
mycharheap()
只是泄漏。您char
使用new 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.
}
Nevertheless, to re-iterate, don't use char*
for strings in C++. Use std::string
.
尽管如此,再次重申,不要char*
在 C++ 中使用字符串。使用std::string
.
回答by Andy Prowl
Function mycharheap()
is leaking: you make your pointer point to a memory region of the length of one char
allocated on the heap, and then you modify that pointer to point to a string literal which is stored in read-only memory. The allocated memory will not be freed.
函数mycharheap()
正在泄漏:您使指针指向char
在堆上分配的长度的内存区域,然后修改该指针以指向存储在只读内存中的字符串文字。分配的内存不会被释放。
回答by Csq
There are no errors in your code just a leaked char
. But it is pretty weird.
您的代码中没有错误,只是一个泄漏的char
. 但这很奇怪。
#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;
}
For the "What you want:" part, Yossarian was faster than me.
对于“你想要什么:”部分,Yossarian 比我快。
回答by geneemailbox1 geneemailbox1
Example below was a question that came up when i was trying to pull information in and out from a function call.
下面的例子是当我试图从函数调用中提取信息时出现的一个问题。
##代码##