我想知道为什么,在这个示例代码中,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
答案 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;
}
答案 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);
}