valgrind发现将指针传递给函数的错误,但是当代码在同一范围内时没有错误

时间:2017-03-29 16:30:39

标签: c++ pointers valgrind

我想知道为什么,在这个示例代码中,valgrind找不到错误或丢失内存:

#include <stdio.h>
#include <stdlib.h>

int main()
{
   char *str;

   /* Initial memory allocation */
   str = (char *) malloc(8);
   strcpy(str, "example");
   printf("String = %s,  Address = %u\n", str, str);

   /* Reallocating memory */
   str = (char *) realloc(str, 14);
   strcat(str, ".com");
   printf("String = %s,  Address = %u\n", str, str);

   free(str);

   return(0);
}

但是,当我用函数替换这些行时:

int main() {
   ...
   /* Reallocating memory */
   newstr(str);
   ...
}

void newstr(char *str) {
   str = (char *) realloc(str, 14);
   strcat(str, ".com");
}

我在valgrind上遇到了19个错误,主要抱怨无效读取。但是,程序执行并输出相同的所有内容,没有错误。当我将str传递给valgrind通知我的内存中发生的函数时,是否会发生一些事情?我该怎么做才能解决这个问题?我怎样才能更多地了解这种行为及其含义?

这是两种情况下程序的输出:

String = example,  Address = 16445456
String = example.com,  Address = 16445456

3 个答案:

答案 0 :(得分:2)

作为一般规则,传递给C函数的参数按值传递。除非您通过引用显式传递,或者将指针传递给您的对象,否则在函数返回时,在被调用函数中所做的更改将不会保留。

在你的情况下,你可能正在传递指针,但是你试图修改函数中的指针,而不是修改指针引用的内容。

除了在返回新指针的其他答案中提供的解决方案外,您有两个选择:

指针指针

void newstr(char **str) {
   *str = (char *) realloc(*str, 25);
   strcat(*str, ".com");
}

<强>参考

void newstr(char *&str) {
   str = (char *) realloc(str, 25);
   strcat(str, ".com");
}

答案 1 :(得分:1)

valgrind正确地抱怨读取,你从无效的内存中读取。你从str的无效值读取。 正确的代码如下。

int main() {
   ...
   /* Reallocating memory */
   str = newstr(str);
   ...
}

char * newstr(char *str) {
   str = (char *) realloc(str, 25);
   strcat(str, ".com");
   return str;
}

image

答案 2 :(得分:1)

通过引用传递允许您(其中包括)更改函数内的引用值。你可以用指针

来做到这一点

但是在

void newstr(char *str) {
   str = (char *) realloc(str, 25); <-- changed the pointer
   strcat(str, ".com"); 
}

函数内部改变的值是指针。因此,您必须通过引用传递指针(或返回BayK所示的更改指针)

void newstr(char *& str) {
   str = (char *) realloc(str, 25);
   strcat(str, ".com");
}

或者你可以接受这种全副武装且可操作的C ++编程语言的强大功能并使用std::string

#include <iostream>
#include <string>
int main()
{
    std::string str = "example";

    std::cout << "String = " << str << ",  Address = "  << &str << "\n";
    str += ".com";
    std::cout << "String = " << str << ",  Address = "  << &str << "\n";
    return(0);
}