在函数中分配后的空指针
Null pointer after allocating in function
我对 C++ 中的指针有疑问。我声明了指针 data 并在函数中对其进行了初始化,但是在我的程序离开函数之后,数据指针为 NULL。我在代码下方提供输出。但是,当我删除行时 getline(cin, desc); pointer data 永远不会是 NULL。为什么会这样?我应该怎么做才能在函数中分配内存 got form getline()?
#include <cstdio>
#include <iostream>
using namespace std;
struct Data
{
string desc;
int number;
};
void function1(int number, string desc, Data *data)
{
data = new Data;
data -> desc = desc;
data -> number = number;
printf("DURING: %p\n", data);
}
int main(int argc, char const *argv[])
{
int number;
string desc = "TEXT TEXT";
getline(cin, desc);
scanf("%i",&number);
Data *data;
printf("BEFORE: %p\n", data);
function1(number,desc,data);
printf("AFTER: %p\n", data);
return 0;
}
输出:
BEFORE: 0x0
DURING: 0x7f9ab25008c0
AFTER: 0x0
但是如果我删除行:getline(cin, desc); OUTPUT:
BEFORE: 0x103de4068
DURING: 0x7f8ed2c04aa0
AFTER: 0x103de4068
您正在按值传递指针,因此该函数从 main
获取指针的副本,并且只能影响它自己的指针副本,而不影响 [=13= 中的指针].
因此,在调用函数之前和之后,指针只是一个未初始化的值,因此它可能会发生不可预测的变化(并且从技术上讲,将其打印出来或以任何其他方式使用它的值会导致未定义的行为).
通过引用传递指针获取修改原指针的函数:
void function1(int number, string desc, Data *&data)
{
data = new Data;
data -> desc = desc;
data -> number = number;
printf("DURING: %p\n", data);
}
然后,当你弄清楚这个问题时,你可能想(几乎)完全停止使用原始指针。几乎总是有更好的方法来做事。在这种情况下,您当前在 function1
中的代码可能应该在构造函数中:
struct Data {
string desc;
int number;
Data(string desc, int number) : desc(desc), number(number) {}
};
...然后在 main
中,您只需定义对象的一个实例:
int main() {
int n;
std::cin >> n;
Data d{"TEXT TEXT", n};
}
你定义了一个指针,但没有给它赋值:
Data *data;
根据定义 *data
可以指向任何东西 "it wants"。因此,BEFORE
和 AFTER
值只是随机地址。
但是,在您的 function1
中,您做的第一件事是为新的数据对象分配内存,并用它覆盖现有的指针,因此显然您的 DURING
值不同并且三者中只有一个有意义
唉,因为你按值传递你的指针,你在 function1
中所做的一切一旦结束就扔掉了。
我假设,您想要的是将 new Data
语句移动到您的 main
我对 C++ 中的指针有疑问。我声明了指针 data 并在函数中对其进行了初始化,但是在我的程序离开函数之后,数据指针为 NULL。我在代码下方提供输出。但是,当我删除行时 getline(cin, desc); pointer data 永远不会是 NULL。为什么会这样?我应该怎么做才能在函数中分配内存 got form getline()?
#include <cstdio>
#include <iostream>
using namespace std;
struct Data
{
string desc;
int number;
};
void function1(int number, string desc, Data *data)
{
data = new Data;
data -> desc = desc;
data -> number = number;
printf("DURING: %p\n", data);
}
int main(int argc, char const *argv[])
{
int number;
string desc = "TEXT TEXT";
getline(cin, desc);
scanf("%i",&number);
Data *data;
printf("BEFORE: %p\n", data);
function1(number,desc,data);
printf("AFTER: %p\n", data);
return 0;
}
输出:
BEFORE: 0x0
DURING: 0x7f9ab25008c0
AFTER: 0x0
但是如果我删除行:getline(cin, desc); OUTPUT:
BEFORE: 0x103de4068
DURING: 0x7f8ed2c04aa0
AFTER: 0x103de4068
您正在按值传递指针,因此该函数从 main
获取指针的副本,并且只能影响它自己的指针副本,而不影响 [=13= 中的指针].
因此,在调用函数之前和之后,指针只是一个未初始化的值,因此它可能会发生不可预测的变化(并且从技术上讲,将其打印出来或以任何其他方式使用它的值会导致未定义的行为).
通过引用传递指针获取修改原指针的函数:
void function1(int number, string desc, Data *&data)
{
data = new Data;
data -> desc = desc;
data -> number = number;
printf("DURING: %p\n", data);
}
然后,当你弄清楚这个问题时,你可能想(几乎)完全停止使用原始指针。几乎总是有更好的方法来做事。在这种情况下,您当前在 function1
中的代码可能应该在构造函数中:
struct Data {
string desc;
int number;
Data(string desc, int number) : desc(desc), number(number) {}
};
...然后在 main
中,您只需定义对象的一个实例:
int main() {
int n;
std::cin >> n;
Data d{"TEXT TEXT", n};
}
你定义了一个指针,但没有给它赋值:
Data *data;
根据定义 *data
可以指向任何东西 "it wants"。因此,BEFORE
和 AFTER
值只是随机地址。
但是,在您的 function1
中,您做的第一件事是为新的数据对象分配内存,并用它覆盖现有的指针,因此显然您的 DURING
值不同并且三者中只有一个有意义
唉,因为你按值传递你的指针,你在 function1
中所做的一切一旦结束就扔掉了。
我假设,您想要的是将 new Data
语句移动到您的 main