C++ 将指针传递到主函数后,无法正确打印内容

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

我正在练习使用指针创建对象和访问数据。我创建了一个名为BigNum的stuct来表示具有多个数字的数字。当我尝试在readDigits函数中打印struct的内容时,可以很好地打印它。但是,在将指针传递给main函数后,stuct的内容将打印为随机数。为什么?如何修复它

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;
}