C++ 从函数返回可变长度数组

C++ 从函数返回可变长度数组,c++,arrays,gcc,variable-length-array,C++,Arrays,Gcc,Variable Length Array,下面的函数“increment”将1添加到表示为数组的数字中 int* increment(int array[], int size, int *sizeLen) { int temp[size+1]; int carry = 0; carry = (array[size-1]+1)/10; temp[size] = (array[size-1]+1)%10; for(int i=size-2;i>=0;i--) {

下面的函数“increment”将1添加到表示为数组的数字中

int*  increment(int array[], int size, int *sizeLen)
{
    int temp[size+1];

    int carry = 0;
    carry = (array[size-1]+1)/10;
    temp[size] = (array[size-1]+1)%10;

    for(int i=size-2;i>=0;i--)
    {
        temp[i+1] = (array[i] + carry)%10;
        carry = (array[i]+carry)/10;
    }
    if(carry)
    {
        temp[0] = 1;
        *sizeLen = size+1;
        return temp;
    }
    else
    {
        *sizeLen = size;
        return (temp+1);
    }
}

int main()
{
    int array[] = {9,9,9};
    int length;
    int *res = increment(array, sizeof(array)/sizeof(int), &length);
    for(int i=0;i<length;i++)
    {
        cout << res[i] << " ";
    }
}
int*增量(int数组[],int大小,int*sizeLen)
{
内部温度[尺寸+1];
整数进位=0;
进位=(数组[size-1]+1)/10;
温度[size]=(数组[size-1]+1)%10;
对于(int i=size-2;i>=0;i--)
{
温度[i+1]=(数组[i]+进位)%10;
进位=(数组[i]+进位)/10;
}
如果(携带)
{
温度[0]=1;
*sizeLen=尺寸+1;
返回温度;
}
其他的
{
*sizeLen=尺寸;
返回(临时+1);
}
}
int main()
{
int数组[]={9,9,9};
整数长度;
int*res=增量(数组、sizeof(数组)/sizeof(int)和长度);

对于(int i=0;i这是未定义的行为。下次程序推送到堆栈时,数据将丢失


专业程序不要依赖于此。

这是未定义的行为。下次程序推送到堆栈时,数据将丢失


专业程序不要依赖它。

你是对的。
temp
确实超出范围,它应该打印垃圾值


但有时它会打印正确的值。因为当当前函数结束时,不会立即清除/覆盖本地堆栈内存。

您是对的。
temp
确实超出范围,它应该打印垃圾值


但有时它会打印正确的值。因为当当前函数结束时,不会立即清除/覆盖本地堆栈内存。

这里的键实际上是数组的存储持续时间。它具有自动存储持续时间。具有自动存储持续时间的变量的生存期在退出其作用域时结束

它完全按照您期望的那样运行,但是C中没有任何东西可以阻止您获取本地对象的地址并从函数返回它

使用该指针是未定义的行为。它可能看起来有效,但数组仍然是“死的”。这种指针通俗地称为“悬空指针”



对于C来说,上述情况是正确的。因为这是关于GCC扩展的,同样适用于大多数情况,但可能需要谨慎对待。

这里的关键确实是数组的存储持续时间。它具有自动存储持续时间。具有自动存储持续时间的变量的生存期在其所在范围为exi时结束特德

它完全按照您期望的那样运行,但是C中没有任何东西可以阻止您获取本地对象的地址并从函数返回它

使用该指针是未定义的行为。它可能看起来有效,但数组仍然是“死的”。这种指针通俗地称为“悬空指针”



对于C来说,上述情况是正确的。因为这是关于GCC扩展的,所以同样适用于大多数情况,但可能需要谨慎对待。

这不起作用。您将返回一个指向本地数组的指针,该数组将在函数返回时被删除(更有可能被过度写入/重新使用)

这样做的C++方法是使用<代码> STD::vector < /COD>。(假设在原来的<代码>大小<代码>和代码> SiZelEN < /代码>中引用了<代码>数组< < />代码中的元素数量,并且分别返回


这将不起作用。您正在返回一个指向本地数组的指针,该数组将在函数返回时立即被删除(更有可能被过度写入/重新使用)

这样做的C++方法是使用<代码> STD::vector < /COD>。(假设在原来的<代码>大小<代码>和代码> SiZelEN < /代码>中引用了<代码>数组< < />代码中的元素数量,并且分别返回


你所看到的是未定义的行为。C.C++的陷阱甚至不支持VLAs,你的代码基本上是使用容器和迭代器。我没有注意到标签。为什么你在VC++中使用VLA(扩展,非标准)?你的问题是关于C吗?请澄清。那些是不同的语言。谢谢大家的帮助。是的,我知道我写了C和C++代码的混合。我对程序的奇怪行为感到好奇。@老鹰-我对程序的奇怪行为感到好奇——试图弄清楚为什么你的程序表现得奇怪。这是一种巨大的时间浪费。为什么?如果你编译了同一个程序,但使用了不同的编译器选项,例如优化,那么程序的行为可能会再次与你看到的不同。试图找出未定义的行为变得毫无意义。你看到的是未定义的行为。这就是C.C++的陷阱甚至不支持VLAs,而且代码基本上是使用容器和迭代器。我没有注意到标签。为什么在VC++代码中使用VLA(扩展,非标准)?你的问题是关于C吗?请澄清。那些是不同的语言。谢谢大家的帮助。是的,我知道我写了C和C++代码的混合。我对程序的奇怪行为感到好奇。@老鹰-我对程序的奇怪行为感到好奇——试图弄清楚为什么你的程序表现得奇怪。成为一个巨大的时间浪费。为什么?如果你编译了同一个程序,但使用了不同的编译器选项,例如优化,那么这个程序的行为可能会再次与你看到的不同。现在,试图找出未定义的行为变得毫无意义。请原谅我的简短。我目前使用的是Android平板电脑。请原谅我的简短。我目前使用的是Android平板电脑。
if(carry)temp.insert(1,temp.begin())有什么问题
?它涉及到将所有元素洗牌,但这并不比您实现的副本更糟。此外,如果您将
进行初始化,将
携带到1,然后在
期间使循环成为
执行,整个过程将变成
std::vector result(array);
(或更好)
std::vector<int> increment(std::vector<int> const&array)
{
    std::vector<int> temp(array.size());
    auto a = array.rbegin();
    auto b = temp.rbegin();
    auto carry = (*a+1)/10;
    *b = (*a+1)%10;
    for(++a,++b; a!=array.rend(); ++a,++b)
    {
        *b = (*a+carry)%10;
        carry = (*a+carry)/10;
    }
    if(carry) { // we must add another element into temp at the start
                // that cannot be done with vector, hence we must create
                // another vector. Note that this should rarely happen.
       std::vector<int> result(temp.size()+1);
       auto r = result.begin();
       *r = 1;
       std::copy(temp.begin(),temp.end(),++r);
       return result;
    } else
       return temp;
}
std::vector<std::uint8_t> increment(std::vector<std::uint8_t> const&input)
{
    std::vector<std::uint8_t> result;
    result.reserve(input.size()+1);
    auto a = input.begin();
    auto carry = (*a+1)/10;
    result.push_back((*a+1)%10);
    for(++a; a!=input.end(); ++a)
    {
        result.push_back((*a+carry)%10);
        carry = (*a+carry)/10;
    }
    if(carry)
        result.push_back(1);
    return result;
}