Valgrind:条件跳转,未初始化值,C++基础代码
Valgrind: Conditional jump, uninitialised value, C++ basic code
这是我的第一个问题,我目前正在学习 C++,并且正在研究如何使用 Valgrind。这个程序一开始有 71 个错误,我已经能够将它减少到 2 个,由于我对 C++ 缺乏经验,我只是想不出剩下的问题。谁能帮我弄清楚这里出了什么问题,或者至少给我指出一个好的方向?我明白错误告诉我的是什么,我只是没有看到问题。感谢您的帮助。
程序代码如下:
#include <iostream>
#include <cstdlib>
using namespace std;
int* initArray(int);
int fillArray(int *, int);
int* doubleArray(int *, int);
void displayArray(int *, int);
int main(int argc, char ** argv){
if (argc != 2){
cout << "wrong number of arguments" << endl;
exit(1);
}
int n = atoi(argv[1]);
srand(time(0));
int* ptr = new int[*initArray(n)]; //***Here is line 38***
fillArray(ptr, n);
displayArray(ptr, n);
int* dptr = doubleArray(ptr, n);
fillArray(ptr, 2*n);
displayArray(ptr, 2*n);
}
int* initArray(int n){
int arr[n];
int *ptr = arr;
return ptr;
}
int fillArray(int *ptr, int n){
for(int i=0; i<n; i++){
ptr[i] = rand() % 100;
}
}
int* doubleArray(int * ptr, int n){
int size = 2 * n;
int * tmp = new int[size];
ptr = tmp;
delete [] tmp;
return ptr;
delete [] ptr;
}
void displayArray(int *ptr, int n){
for(int i=0; i<n; i++){
cout << ptr[i] << " ";
}
cout << endl;
}
这是我从 valgrind 输出的错误:
http://i.imgur.com/881nsDw.png
(它说我需要 10 个声誉才能 post 它作为图像,抱歉!)
正如 WhozCraig 正确指出的那样,您的问题之一在于函数 initArray
。我不确定你想在其中实现什么,但对我来说,你可以简单地省略它并在第 38 行使用 int* ptr = new int[n];
。
本质上,您返回了指向堆栈上未初始化内存的指针,然后尝试分配大小等于它指向的任何大小的数组。 Valgrid 消息告诉你了。
但是在你触发 UB 之后(在 initArray
中)你的程序合法地可以做 任何事情。
但是你的代码中还有更多的错误:
- 在退出
main
之前,您没有 delete
d 由 ptr
指向的数组。
- 您不能通过分配指针来复制数组的内容 (
ptr = tmp
)。为此,您需要遍历数组并逐个复制元素。
- 你的语句
delete [] ptr;
将永远不会被执行。
还有一个一般说明:如果学习指针不是您的目标,请避免使用它们——在您的情况下,正确的解决方案是使用 std::vector
。
这是我的第一个问题,我目前正在学习 C++,并且正在研究如何使用 Valgrind。这个程序一开始有 71 个错误,我已经能够将它减少到 2 个,由于我对 C++ 缺乏经验,我只是想不出剩下的问题。谁能帮我弄清楚这里出了什么问题,或者至少给我指出一个好的方向?我明白错误告诉我的是什么,我只是没有看到问题。感谢您的帮助。
程序代码如下:
#include <iostream>
#include <cstdlib>
using namespace std;
int* initArray(int);
int fillArray(int *, int);
int* doubleArray(int *, int);
void displayArray(int *, int);
int main(int argc, char ** argv){
if (argc != 2){
cout << "wrong number of arguments" << endl;
exit(1);
}
int n = atoi(argv[1]);
srand(time(0));
int* ptr = new int[*initArray(n)]; //***Here is line 38***
fillArray(ptr, n);
displayArray(ptr, n);
int* dptr = doubleArray(ptr, n);
fillArray(ptr, 2*n);
displayArray(ptr, 2*n);
}
int* initArray(int n){
int arr[n];
int *ptr = arr;
return ptr;
}
int fillArray(int *ptr, int n){
for(int i=0; i<n; i++){
ptr[i] = rand() % 100;
}
}
int* doubleArray(int * ptr, int n){
int size = 2 * n;
int * tmp = new int[size];
ptr = tmp;
delete [] tmp;
return ptr;
delete [] ptr;
}
void displayArray(int *ptr, int n){
for(int i=0; i<n; i++){
cout << ptr[i] << " ";
}
cout << endl;
}
这是我从 valgrind 输出的错误: http://i.imgur.com/881nsDw.png (它说我需要 10 个声誉才能 post 它作为图像,抱歉!)
正如 WhozCraig 正确指出的那样,您的问题之一在于函数 initArray
。我不确定你想在其中实现什么,但对我来说,你可以简单地省略它并在第 38 行使用 int* ptr = new int[n];
。
本质上,您返回了指向堆栈上未初始化内存的指针,然后尝试分配大小等于它指向的任何大小的数组。 Valgrid 消息告诉你了。
但是在你触发 UB 之后(在 initArray
中)你的程序合法地可以做 任何事情。
但是你的代码中还有更多的错误:
- 在退出
main
之前,您没有delete
d 由ptr
指向的数组。 - 您不能通过分配指针来复制数组的内容 (
ptr = tmp
)。为此,您需要遍历数组并逐个复制元素。 - 你的语句
delete [] ptr;
将永远不会被执行。
还有一个一般说明:如果学习指针不是您的目标,请避免使用它们——在您的情况下,正确的解决方案是使用 std::vector
。