valgrind 发现错误将指针传递给函数,但当代码在同一范围内时没有错误
valgrind finds errors passing pointer to function, but no errors when the code is in the same scope
我想知道为什么在此示例代码中,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
valgrind 抱怨读取正确,你从无效内存中读取。您从 str 的无效值中读取。
更正以下代码。
int main() {
...
/* Reallocating memory */
str = newstr(str);
...
}
char * newstr(char *str) {
str = (char *) realloc(str, 25);
strcat(str, ".com");
return str;
}
作为一般规则,传递给 C 函数的参数按值传递。除非你显式地通过引用传递,或者传递一个指向你的对象的指针,否则在函数 returns 时,被调用函数中所做的更改将不会持续存在。
在你的情况下,你可能正在传递一个指针,但你试图在函数中修改指针而不是修改指针引用的内容。
除了在 return 新指针的另一个答案中提供的解决方案外,您还有两个选择:
指向指针的指针
void newstr(char **str) {
*str = (char *) realloc(*str, 25);
strcat(*str, ".com");
}
参考
void newstr(char *&str) {
str = (char *) realloc(str, 25);
strcat(str, ".com");
}
通过引用传递,除其他外,您可以更改函数内的引用值。你可以用一个指针来做到这一点
但是在
void newstr(char *str) {
str = (char *) realloc(str, 25); <-- changed the pointer
strcat(str, ".com");
}
函数内部改变的值是指针。因此,您必须通过引用传递指针(或 return 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);
}
我想知道为什么在此示例代码中,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
valgrind 抱怨读取正确,你从无效内存中读取。您从 str 的无效值中读取。 更正以下代码。
int main() {
...
/* Reallocating memory */
str = newstr(str);
...
}
char * newstr(char *str) {
str = (char *) realloc(str, 25);
strcat(str, ".com");
return str;
}
作为一般规则,传递给 C 函数的参数按值传递。除非你显式地通过引用传递,或者传递一个指向你的对象的指针,否则在函数 returns 时,被调用函数中所做的更改将不会持续存在。
在你的情况下,你可能正在传递一个指针,但你试图在函数中修改指针而不是修改指针引用的内容。
除了在 return 新指针的另一个答案中提供的解决方案外,您还有两个选择:
指向指针的指针
void newstr(char **str) {
*str = (char *) realloc(*str, 25);
strcat(*str, ".com");
}
参考
void newstr(char *&str) {
str = (char *) realloc(str, 25);
strcat(str, ".com");
}
通过引用传递,除其他外,您可以更改函数内的引用值。你可以用一个指针来做到这一点
但是在
void newstr(char *str) {
str = (char *) realloc(str, 25); <-- changed the pointer
strcat(str, ".com");
}
函数内部改变的值是指针。因此,您必须通过引用传递指针(或 return 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);
}