混淆 C++ 语言中的字符串重复

Posted

技术标签:

【中文标题】混淆 C++ 语言中的字符串重复【英文标题】:Confusion with duplication of string in C++ language 【发布时间】:2017-06-22 16:40:55 【问题描述】:

每次遇到处理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"

【问题讨论】:

这不是C..这个混淆应该先清除。 不要在c++中使用c-strings,你永远不会有问题。 第二个函数不会从main修改char* text 看看这个例子:coliru.stacked-crooked.com/a/87e2070b354a7f4e 把getText2里的文字改成“BBBBB”就可以看到这个了。 【参考方案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");

然后使用指向参数的指针间接传递参数。所以在函数内部,参数的值发生了变化。

【讨论】:

谢谢弗拉德。关于内存泄漏的意见非常有用。【参考方案2】:

在第一种情况下,您传递了一个指向本地指针的指针,取消引用该指针并使其指向strdup() 返回的值,您正在修改原始指针指向的地址。

在第二个中,你传递指针本身,你不能在函数内部改变它,因为即使两个指针最初指向同一个内存,它们存储在不同的地方,所以改变一个的地址不会影响对方。

如果你改变了指针指向的数据,而不是getText2()中的地址,那么它就会改变,就像

text[0] = 'B';
text[1] = 'B';
text[2] = 'B';
text[3] = 'B';
text[4] = 'B';

你也应该在使用strdup()返回的指针后调用free(),否则会发生内存泄漏。

最后,在 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++。

【讨论】:

为了让它成为“真正的”C++,它应该是std::string getText()

以上是关于混淆 C++ 语言中的字符串重复的主要内容,如果未能解决你的问题,请参考以下文章

strtol 等人的规范中的混淆语言

C ++中的常量混淆[重复]

如何在c++的字符串中删除某个字符串

在 C++ 中删除字符串中的连续重复字符

[LeetCode] Longest Substring Without Repeating Characters 最长无重复字符的子串 C++语言 java语言实现

从无符号字符到 std::string 的 C++ 转换 [重复]