在不为阵列分配内存的情况下工作

时间:2014-03-25 22:40:54

标签: c++ memory-management

我的朋友做了这个代码。 它工作正常。 目标是将数字的每个数字分成数组的每个元素。 但是a的内存没有分配到任何地方。 知道这个是怎么工作的吗?

    #include<iostream> 
    #include<math.h> 
    using namespace std; 

    int* arrray(int num, int *x){ 
        int len=0; 
        while(num!=0){ 
            x[len]=num%10; 
            num/=10; 
            len++; 
        }  
        return x; 
    } 
    int main(){ 
        int num1=123;  
        int l=0,k=0; 
        int *a=arrray(num1,a); 
        int n1[3]; 
        for(int i=2;i>=0;i--){ 
            n1[l]=a[i]; l++; 
        } 

    }

2 个答案:

答案 0 :(得分:2)

您可以在声明它的同一行使用变量:

int* a = foo(a);

虽然你可以制作defined behavior这样做,但在你的情况下它是不安全的并且会执行未定义的行为(就个人而言,我认为不应该采用这种用法) )。

未分配的C ++变量包含未定义的值。可以为零,可以是从该内存位置中存在的最后一个变量中保留的值。我们通常将此数据称为garbage。使用垃圾值作为指针地址是不安全的。它可能“正常工作”,可能会“出错”并中止您的应用程序。您会发现这些相同的代码有时会工作,并会中止其他时间,甚至会导致其他意外行为(甚至可能会破坏它自己的堆栈)。这很大程度上取决于编译器,环境和随机运气。

可以假设程序员在这种情况下犯了错误(正如您所怀疑的那样),它确实应该使用分配的空间。

注意在调试模式下在visual studio中运行此代码,会触发断言:

Run-Time Check Failure #3 - The variable 'a' is being used without being initialized.

编辑2 此代码还存在其他问题,不仅a未初始化且指针正在未分配的空间上使用。方法arrray正在处理一个指针,它没有关于它所指向的数组大小的信息(假设)。之后,回到mainfor循环假定从索引2(包含)迭代到0是安全的。

此外,因为arrray从不分配空间,并且将数组作为参数,所以不必返回指针。并不是说这是错的,从技术上讲,它实际上可以是一种风格的选择,我只是指出它没有必要。返回写入的位数可能更有意义。

此外,num可以从零开始,这似乎是有效的。

也许更好的arrray方法看起来像这样:

int separateDigits(int num, int* p, int size)
{
  int digitsWritten = 0;

  for (int index = 0; index < size; index++)
  { 
    p[index] = num % 10; 
    num /= 10;
    digitsWritten++;

    if (num == 0)
      break;
  }

  return digitsWritten;
}

然后main可以使用结果:

int main()
{ 
  int num1 = 123;
  const int size = 10;
  int a[size];
  int digitsWritten = separateDigits(num1, a, size); 

  int n1[size]; 

  for(int i = 0; i < digitsWritten; i++)
  { 
    n1[i] = a[digitsWritten - i - 1];
  }

  return 0;
}

答案 1 :(得分:2)

Visual C ++

error C4700: uninitialized local variable 'a' used

Cygwin 64位

它确实编译并运行,遗憾的是代码的第8行有一个segmentation fault,因为array a未初始化。

这是有效的,因为它是未定义的行为,即使会有警告:

warning: 'a' is used uninitialized in this function [-Wuninitialized]或Visual C ++的错误。

无论如何,请记住Scott Meyers的Effective C ++:第47项:确保非本地静态对象在使用之前已初始化。我知道这是针对非本地静态对象的,但一般情况下你应该初始化你的变量。