为啥 const char* 返回值丢失了两个字符?但是在返回之前打印正确的值[重复]

Posted

技术标签:

【中文标题】为啥 const char* 返回值丢失了两个字符?但是在返回之前打印正确的值[重复]【英文标题】:Why is const char* returning value with two characters lost ? However prints the right value just before returning [duplicate]为什么 const char* 返回值丢失了两个字符?但是在返回之前打印正确的值[重复] 【发布时间】:2013-12-24 07:26:09 【问题描述】:

这是我的名为 trim 的函数,它会去除一串引号:

const char* trim(const char* c) 

const char *pos = c;
//Getting the length of the string
int c_length = 0;
   while (*pos != '\0') 
       c_length++;
       pos++;
   

cout<<"\nThis is the length of string:"<<c_length;
char c_store[c_length-2]; // Removing two for the quotes 
pos = c; 
const char* quote = "\"";
char ch;
int i;
for (i = 0; *pos != '\0'; pos++)
    ch = (char)*pos;
    if(ch!=*quote)                            
        c_store[i] = (char)*pos;
        i++;            
    

c_store[i]='\0';   // Adding the null terminating character
const char * c_trimmed = c_store;
cout<<c_trimmed;     // Prints the string CORRECTLY here !!
return c_trimmed;    // There is problem when it returns, see main

现在我正在读取 json::value 对象,使用 toStyledString() 将值转换为字符串,然后使用 c_str() 将其转换为 const char*。我发现这个字符串有引号,所以我将这个值传递给函数 trim。当值返回时,返回的字符串最后被两个字符截断。这是我认为问题所在的主要地方:

int main(int argc, char** argv) 

// Reading json config file into a Json::Value type
char* config_file = read_file_into_string(argv[1]);
Json::Value Bootloading_config = create_json_object(config_file);

const char* bucket_name_json = Bootloading_config["Bootloading"]["bucket_name"].toStyledString().c_str(); // Storing value from json

const char* bucket_name_trimmed = trim(bucket_name_json); // Using trim function

const char* bucket_name = "nikhil-hax"; // Assigning another pointer for comparison

printf("\n Trimmed bucket_name:%s", bucket_name_trimmed); // It is printing the string  with the last two chars cut out

if(strcmp(bucket_name_trimmed,bucket_name) == 0) // To check
    cout<<"\nTRIM function Worked!!";
else cout<<"\nNOT working, look closer";


是否存在内存泄漏或我忽略的其他细节?一些帮助将不胜感激。谢谢

【问题讨论】:

局部变量是局部的。不要返回任何局部变量的地址。 【参考方案1】:

首先,声明一个局部变量:

char c_store[c_length-2]; // Removing two for the quotes 

然后,您将 指针 复制到分配的内存(不是它的内容!):

const char * c_trimmed = c_store;

现在c_trimmed 指向与c_store 相同的内存空间。然后打印出来:

cout<<c_trimmed;     // Prints the string CORRECTLY here !!

然后你从函数中返回它:

return c_trimmed;    

然后c_trimmedc_store指向的内存被自动释放:


从函数返回后,其结果不再指向内存中的有效位置。如果你想从函数返回一个 c 风格的字符串,你必须为它分配内存。比如:

char * c_trimmed = new char[c_length-2];
strcpy(c_trimmed, c_store);
return c_trimmed;

// Don't forget to delete[] the result of this function when it is no longer needed
// or else you'll end up with memory leak

底注。如果您真的使用 C++ 而不是 C 编写,请改用 std::string - 您将遇到现在(以及将来)遇到的一半问题。

【讨论】:

啊,我明白了,局部变量作用域在 trim 函数结束时完成,因此必须为返回的指针分配新的内存。非常感谢 Spook 是不是因为内存自动添加到std::string?是的,我目前正在使用 C 和 C++ 的奇怪组合,因为我用于我的程序的大多数外部库都是用 C 编写的。 std::string 负责内存操作。例如,如果您只是从函数中返回一个本地 std::string,它会自动将数据(取决于您使用的 C++ 版本)复制或移动到外部实例,这样您就不必担心变量范围。此外,std::string 操作更容易执行、更安全(您通常甚至没有太多机会泄漏内存或处理无效内存),有时甚至比C 风格的字符串。如果您使用 C++ 编写代码,我强烈建议您使用 std 类。

以上是关于为啥 const char* 返回值丢失了两个字符?但是在返回之前打印正确的值[重复]的主要内容,如果未能解决你的问题,请参考以下文章

可以/为啥在返回类型中使用 char * 而不是 const char * 会导致崩溃?

C++标准库 如何连接两个const char *类型字符串,并返回const char * 类型结果?

为啥 std::string_view 比 const char* 快?

为啥我可以从 char * const 值创建 char * 向量?

将字符串从 std::string 转换为 const char * 时出现数据丢失问题

为啥 const QString& 参数返回错误的 const char* 指向数据的指针