如何从函数返回字符串文字

发布于 2024-08-26 09:23:15 字数 377 浏览 10 评论 0原文

我总是对从函数返回字符串文字或字符串感到困惑。有人告诉我可能存在内存泄漏,因为你不知道内存什么时候会被删除?

例如下面的代码中,如何实现foo(),使得代码的输出为“Hello World”?

void foo (       )              // you can add parameters here.
{

}

int main ()
{
    char *c;
    foo (    );
    printf ("%s",c);
    return 0;
}

另外,如果foo()的返回类型不是void,但可以返回char*,那么它应该是什么?

I am always confused about return a string literal or a string from a function. I was told that there might be memory leak because you don't know when the memory will be deleted?

For example, in the code below, how to implement foo() so as to make the output of the code is "Hello World"?

void foo (       )              // you can add parameters here.
{

}

int main ()
{
    char *c;
    foo (    );
    printf ("%s",c);
    return 0;
}

Also, if the return type of foo() is not void, but you can return char*, what should it be?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我乃一代侩神 2024-09-02 09:23:15

我假设我们无法修改 main.为了让你的程序在没有泄漏的情况下工作,你需要一些东西来静态存储:

void foo(char*& pC)  // reference
{
    static char theString[] = "thingadongdong";

    pC = theString;
}

但实际上,这不是非常传统的 C++ 代码。您将使用 std::stringstd::cout,因此您不必担心内存:

std::string foo(void)
{
    return "better thingadongdong";
}

int main(void)
{
    // memory management is done
    std::cout << foo() << std::endl;
}

如果您'如果你想知道是否需要手动释放某些东西,那就是做错了。

I'm assuming we cannot modify main. To get your program working without a leak, you need something to have static storage:

void foo(char*& pC)  // reference
{
    static char theString[] = "thingadongdong";

    pC = theString;
}

But really, this isn't very conventional C++ code. You'd be using std::string and std::cout, so you don't have to worry about memory:

std::string foo(void)
{
    return "better thingadongdong";
}

int main(void)
{
    // memory management is done
    std::cout << foo() << std::endl;
}

If you're wondering if something needs to be manually deallocated, it's being done wrong.

┈┾☆殇 2024-09-02 09:23:15

由于 char* 的旧用法已被弃用,因此您不能简单地使用字符串吗?

const char* func1 () {return "字符串文字";}

string func2 () {return "另一个字符串文字";}

这两个都可以正常工作,无需编译器警告。

但是

char* func3 () {return "yet another stringliteral";}

根本无法编译。 的

char* func4 () {return &"对字符串文字的引用?";}

Stroustrup 在《C++ 编程语言》(第三版)中说:

“字符串文字是静态分配 这样,从函数返回一个

const char* error_message (int i)`
{
//...
return "range error";
}

错误消息的内存就不会在调用 error_messages() 后消失。”

因此,程序中的每个字符串文字都分配在自己的一小块内存中,该内存块在程序运行期间持续存在(即静态分配)。
将 const 放在 char* 前面可以让编译器知道您不打算(也不能)更改该字符串文字的一小块内存,这可能很危险,因此尽管从字符串文字转换为 char* ,它们还是让这个分配滑动已弃用。

相反,返回字符串必须将字符串文字复制到字符串类型的对象中,即调用者负责的内存中。

无论哪种方式,都不会出现内存泄漏:每个字符串文字都有自己的一块内存,该内存在程序终止时会被清除; return to const char* 返回一个指向文字内存块的指针(知道你不能改变它);并返回字符串将副本复制到调用者代码中存在的字符串对象中,该对象由调用者清理。

虽然在符号方面看起来有点难看,但我猜他们留下了 const char* 以保留廉价的替代方案(不涉及副本)。

Since the old use of char* is being deprecated, can you not simply use a string?

const char* func1 () {return "string literal";}

string func2 () {return "another string literal";}

Both of these work fine, with no compiler warnings.

However

char* func3 () {return "yet another string literal";}

will not compile at all. Nor will

char* func4 () {return &"a ref to a string literal?";}

Stroustrup says in "The C++ Programming Language" (Third Edition):

"A string literal is statically allocated so that it is safe to return one from a function.

const char* error_message (int i)`
{
//...
return "range error";
}

The memory holding range error will not go away after a call of error_messages()."

So every string literal in a program is allocated in its own little piece of memory that lasts for the duration of the program (i.e. is statically allocated).
Putting the const in front of the char* lets the compiler know that you do not intend (and cannot) alter that string literal's little piece of memory which could be dangerous, so they let this assignment slide despite that conversion from string literal to char* is deprecated.

Returning instead to a string must copy the string literal into an object of type string, memory that the caller is responsible for.

Either way there are no memory leaks: every string literal gets its own piece of memory that is cleaned up on program termination; return to const char* returns a pointer to a literal's piece of memory (knowing you cannot alter it); and return to a string makes a copy into a string object existing in the caller's code which is cleaned up by the caller.

Though it seems a little ugly notation-wise, I'm guessing they left the const char* to keep the cheap alternative (involving no copies).

诗笺 2024-09-02 09:23:15

我总是对从函数返回字符串文字或字符串感到困惑。

不可变的文字字符串

据我了解,如果返回类型声明为 const,则可以安全地直接返回字符串文字,以声明该字符串不打算被更改。这意味着您不必担心字符串/内存泄漏的寿命。

可变的非文字字符串

但是,如果您需要一个可以就地更改的字符串,则需要考虑该字符串的生命周期以及存储该字符串的内存分配的大小。
这成为一个问题,因为您不能再为函数的每次调用轻松地返回包含字符串的相同内存,因为先前的使用可能已经更改了该内存的内容,和/或可能仍在使用中。因此必须分配一块新的内存来保存返回的字符串。

这是可能发生泄漏的地方,也是需要选择在哪里进行分配和解除分配的地方。您可以让函数本身分配内存,并在文档中声明发生这种情况,并在其中规定调用者必须在不再需要内存时释放内存(防止泄漏)。这意味着该函数可以简单地返回一个 char *。

另一种选择是将一些内存传递给调用者分配的函数,并让函数将字符串放置在该内存中。在这种情况下,调用者既分配又负责释放该内存。

最后,我提到使用可变字符串时需要管理内存和字符串的大小。分配的空间需要足够大,既可以容纳函数最初设置的字符串,也可以容纳在函数之后、释放内存之前进行的任何更改。如果未能正确执行此操作,可能会将字符串写入 long 以适应最初分配的内存,从而导致缓冲区溢出;这对程序的健康和安全极其危险。它可能会导致极难发现的错误和安全漏洞(因为错误的根源 - 溢出 - 可能与程序失败时看到的症状相去甚远)。

I am always confused about return a string literal or a string from a function.

Immutable, literal string

As I understand it, you are safe to return a string literal directly if the return type is declared const, to declare that the string is not intended to be altered. This means you needn't worry about the lifespan of the string / memory leaks.

Mutable, non-literal string

However, if you need a string that you can change in-place, you need to consider the lifespan of the string and the size of the memory allocation in which it is stored.
This becomes an issue, since you can no longer blithely return the same memory containing string for each invocation of the function, since a previous use could have altered the contents of that memory, and/or may still be in use. Hence a new piece of memory must be allocated to hold the string returned.

This is where the potential for a leak occurs, and where the choice needs to be made about where the allocation and de-allocation should occur. You could have the function itself allocate the memory and state in the documentation that this happens and stipulate therein that the caller has to free the memory when it is no longer required (preventing a leak). This means the function can simply return a char *.

The other option is to pass in some memory to the function that was allocated by the caller, and have the function place the string inside that memory. In this case, the caller both allocates and is responsible for freeing that memory.

Finally, I mentioned that the size of the memory and string need to be managed when using a mutable string. The allocation needs to be both large enough for the string initially set by the function and also for any changed that are made after the function, before the memory is freed. Failing to do this correctly can cause a buffer overflow by writing a string to long to fit in the memory initially allocated; this is extremely dangerous to the health and security of your program. It can cause bugs and security holes that are extremely hard to spot (since the source of the error - the overflow - can be far removed from the symptoms seen when the program fails).

待"谢繁草 2024-09-02 09:23:15

像这样的东西:

void foo(char ** pChar)
{
    // Make sure the string is shorter
    // than the buffer
    *pChar = new char[256];
    strcpy(*pChar,"Hello World!");
}

然后像这样调用它:

foo(&c);

正如评论中提到的,要小心您存储的字符串小于缓冲区,否则您将得到...堆栈溢出! (双关语)

Something like this:

void foo(char ** pChar)
{
    // Make sure the string is shorter
    // than the buffer
    *pChar = new char[256];
    strcpy(*pChar,"Hello World!");
}

Then call it like this:

foo(&c);

As mentioned in the comment, be careful the string you are storing is smaller than the buffer or you will get a... stack overflow! (Pun intended)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文