C++ 将指针传递到主函数后,无法正确打印内容
我正在练习使用指针创建对象和访问数据。我创建了一个名为BigNum的stuct来表示具有多个数字的数字。当我尝试在readDigits函数中打印struct的内容时,可以很好地打印它。但是,在将指针传递给main函数后,stuct的内容将打印为随机数。为什么?如何修复它C++ 将指针传递到主函数后,无法正确打印内容,c++,pointers,function-pointers,C++,Pointers,Function Pointers,我正在练习使用指针创建对象和访问数据。我创建了一个名为BigNum的stuct来表示具有多个数字的数字。当我尝试在readDigits函数中打印struct的内容时,可以很好地打印它。但是,在将指针传递给main函数后,stuct的内容将打印为随机数。为什么?如何修复它 struct BigNum{ int numDigits; //the number of digits int *digits; //the content of the big num }; int
struct BigNum{
int numDigits; //the number of digits
int *digits; //the content of the big num
};
int main(){
BigNum *numPtr = readDigits();
for (int i=0; i<(numPtr->numDigits);i++ ){
std::cout << (numPtr->digits)[i] << std::endl;
}
return 0;
}
BigNum* readDigits(){
std::string digits;
std::cout << "Input a big number:" << std::endl;
std::cin >> digits;
int result[digits.length()];
toInt(digits,result);
BigNum *numPtr = new BigNum();
numPtr->numDigits = digits.length();
numPtr->digits = result;
/* When I try to print in here, it's totally okay!
std::cout << "Here is the content:" << std::endl;
for (int i=0; i<numPtr->numDigits;i++ ){
std::cout << (numPtr->digits)[i] << std::endl;
}
*/
return numPtr;
}
void toInt(std::string& str, int result[]){
for (int i=0;i<str.length() ;i++ ){
result[str.length()-i-1] = (int)(str[i]-'0');
}
}
struct BigNum{
int numDigits;//位数
int*digits;//大数值的内容
};
int main(){
BigNum*numpr=readDigits();
对于(int i=0;inumDigits);i++){
std::cout digits)[i]numDigits=digits.length();
numPtr->数字=结果;
/*当我试着在这里打印时,它完全没问题!
std::cout您有未定义的行为,因为您将自动对象的地址分配给数字
指针。当readDigits()
返回时,此内存不再有效。您应该将基于堆的对象的指针地址分配给此指针(或某些等效对象,例如使用向量或智能指针):
result
存储在堆栈上。因此,如果将其作为numpr
的一部分返回,则一旦退出函数,它将无效。您必须使用new
将其分配到函数BigNum*readDigits()
您将apointer分配给堆栈内存到新分配的BigNum的指针:
int result[digits.length()]; // <--- variable is on the stack!!!
toInt(digits,result);
BigNum *numPtr = new BigNum();
numPtr->numDigits = digits.length();
numPtr->digits = result; // <--- make pointer to stack memory available to caller of readDigits
int-result[digits.length()];//numDigits=digits.length();
numPtr->digits=result;//数字是可以的,因为结果的内存在堆栈上仍然有效(只要您在readDigits内)。一旦您离开了`readDigits()',结果的内存将根据您的操作(调用其他函数,…)被覆盖
现在我甚至想知道为什么你没有得到一个编译器错误,'int result[digits.length()];'',因为'digits.length()')不是常数,并且所需堆栈内存的大小必须在编译时定义…所以我认为结果的大小实际上是0…?,这将是一个很好的测试
我的建议是修改readDigits的代码,如下所示:
BigNum* readDigits()
{
std::string digits;
int i;
std::cout << "Input a big number:" << std::endl;
std::cin >> digits;
//int result[digits.length()];
//toInt(digits,result);
BigNum *numPtr = new BigNum();
numPtr->numDigits = digits.length();
numPtr->digits = (int *)malloc(sizeof(int) * numPtr->numDigits); // allocate heap memory for digits
toInt(digits, numPtr->digits);
/* When I try to print in here, it's totally okay!
std::cout << "Here is the content:" << std::endl;
for (i = 0; i <numPtr->numDigits; i++)
{
std::cout << (numPtr->digits)[i] << std::endl;
}
*/
return numPtr;
}
BigNum*readDigits()
{
std::字符串数字;
int i;
std::cout数字;
//int结果[digits.length()];
//toInt(数字、结果);
BigNum*numpr=new BigNum();
numPtr->numDigits=digits.length();
numPtr->digits=(int*)malloc(sizeof(int)*numPtr->numDigits);//为数字分配堆内存
toInt(数字,numPtr->数字);
/*当我试着在这里打印时,它完全没问题!
std::cout这个答案是正确的。它也会引发内存泄漏问题。最好学会使用std::unique_ptr
。我必须使用“new”来修复它吗?还有其他替代方法吗?正如Chris所建议的,使用向量作为readDigits
函数的返回值会更好。这几乎是正确的。让我们忽略“在堆栈上”,并讨论存储持续时间/范围。悬空指针。让我们不要在堆栈上使用这个过时的"术语,而不是有用地谈论存储持续时间/范围。@LightnessRacesinOrbit是否过时,但这就是变量所在的位置。我同意在类的上下文中,谈论变量范围更为统一。但我不能关闭嵌入式程序员的灵魂……不,你根本不知道变量是否在这里le是。绝对没有!@LightnessRacesinOrbit然后做一个小实验:编写一个不带参数的小函数,增加一个全局变量并调用它自己。等待堆栈溢出,检查完成的递归数。然后添加int x[20];
调用函数并再次运行它。如果检查递归次数,您将看到差异。了解堆栈大小,您将注意到差异大于简单的int*推到堆栈上。因此int x[20]在堆栈上(并且int result[digits.length()];
基本相同)。您也可以检查反汇编……即使在不同版本之间,反汇编也可能有所不同。我们以抽象的术语进行讨论是有原因的。您的观察结果通常是正确的,但不能依赖或假设。
BigNum* readDigits(){
//....
int result[digits.length()];
//....
numPtr->digits = result;
return numPtr;
}
int result[digits.length()]; // <--- variable is on the stack!!!
toInt(digits,result);
BigNum *numPtr = new BigNum();
numPtr->numDigits = digits.length();
numPtr->digits = result; // <--- make pointer to stack memory available to caller of readDigits
BigNum* readDigits()
{
std::string digits;
int i;
std::cout << "Input a big number:" << std::endl;
std::cin >> digits;
//int result[digits.length()];
//toInt(digits,result);
BigNum *numPtr = new BigNum();
numPtr->numDigits = digits.length();
numPtr->digits = (int *)malloc(sizeof(int) * numPtr->numDigits); // allocate heap memory for digits
toInt(digits, numPtr->digits);
/* When I try to print in here, it's totally okay!
std::cout << "Here is the content:" << std::endl;
for (i = 0; i <numPtr->numDigits; i++)
{
std::cout << (numPtr->digits)[i] << std::endl;
}
*/
return numPtr;
}
int main()
{
BigNum *numPtr = readDigits();
int i;
for (i = 0; i < (numPtr->numDigits); i++)
{
std::cout << (numPtr->digits)[i] << std::endl;
}
free(numPtr->digits); // free memory allocated by readDigits(..)
return 0;
}