我一直在用c中的指针和内存分配挣扎一段时间。
这是我对max subarray问题的实现。它似乎工作正常(可能有错误)。但我有一个关于元组struct对象的内存存储的问题。如您所见,元组在全局存储中声明。稍后在findMaxSubArray()函数中,声明了三个指向Tuple结构的指针。我的问题是我们没有声明Tuple struct对象实例指针(左,右,交叉)正在解决指针解引用(即,left-> sum等)如何工作。 GNU c编译器是否自动为它们分配存储空间? (我不明白x86汇编代码)有人可以解释一下这里发生了什么吗?非常感谢。
#include <iostream>
using namespace std;
#define NEGINFINITY -2 << 31
typedef struct {
int lowPosition;
int highPosition;
int sum;
} Tuple;
Tuple tuple;
Tuple* findMaxCrossingSubArray(int a[], int low, int mid, int high) {
int leftSum, rightSum;
int leftMax, rightMax;
int sum;
leftSum = rightSum = NEGINFINITY;
sum = 0;
for (int i = mid; i >= low; --i) {
sum += a[i];
if (sum > leftSum) {
leftSum = sum;
leftMax = i;
}
}
sum = 0;
for (int j = mid + 1; j <= high; ++j) {
sum += a[j];
if (sum > rightSum) {
rightSum = sum;
rightMax = j;
}
}
tuple.lowPosition = leftMax;
tuple.highPosition = rightMax;
tuple.sum = leftSum + rightSum;
return &tuple;
}
Tuple* findMaxSubArray(int* array, int low, int high) {
Tuple *left, *right, *cross;
if (high == low) {
// base case
tuple.lowPosition = low;
tuple.highPosition = high;
tuple.sum = array[low];
return &tuple;
}
else {
int mid = (low + high) / 2;
left = findMaxSubArray(array, low, mid);
right = findMaxSubArray(array, mid + 1, high);
cross = findMaxCrossingSubArray(array, low, mid, high);
if (left->sum > right->sum && left->sum > cross->sum)
return left;
else if (right->sum > left->sum && right->sum > cross->sum)
return right;
else
return cross;
}
}
int main() {
Tuple *result;
int data[] = {1, -2, 3, 10, -4, 7, 2, -5};
result = findMaxSubArray(data, 0, 7);
for (int i = 0; i < 8; ++i)
cout << data[i] << " ";
cout << endl;
cout << "The sum of max subarray is " << result->sum
<< " Starting at index " << result->lowPosition
<< " ending at index " << result->highPosition << endl;
}
答案 0 :(得分:1)
全局变量tuple
是此程序中唯一的实际Tuple
。全局变量的内存由编译器管理。
在main
中,Tuple *result
只是一个指针,当你声明它时,它包含一个随机数(无论以前在它现在占据的空间中发生了什么),因此result
指向垃圾(不是有效的Tuple
对象)。
然后您将findMaxSubArray
的结果分配给tuple
。由于findMaxSubArray
返回&tuple
(以某种方式),这是一个全局变量,result
指向全局变量tuple
。因此,当您执行result->sum
时,它与执行tuple.sum
相同。
在findMaxSubArray
中,行Tuple *left, *right, *cross;
声明了三个指向Tuple
的指针,其中包含垃圾值。在if
的一个分支中,您不使用它们,只返回&tuple
,即全局变量tuple
的地址。在另一个分支中,您将left
,right
和cross
设置为findMaxCrossingSubArray
或findMaxSubArray
,它们都以&tuple
单向返回,或者另一个。
我建议你阅读一本关于C ++的书,并在使用C ++时忘记你所知道的关于C的所有内容(但是当你再次编程C时,请记住这一切)。它们不是同一种语言。这段代码充斥着您从C培训中学到的东西(例如#define
和typedef struct ... Tuple
),C ++提供了更好的设施。
答案 1 :(得分:1)
实际分配的唯一Tuple
是全局范围内的tuple
。所有指向Tuple
的指针,例如Tuple* left
只是指向全局存储。例如在:
left = findMaxSubArray(array, low, mid);
right = findMaxSubArray(array, mid + 1, high);
您会发现left
和right
都指向同一地址,因此指向相同的值。
如果没有详细说明,并注意到这是C ++,而不是C,您可以将Tuple*
返回类型更改为Tuple
返回值并使用自动(堆栈)存储。
代码变成了:
Tuple findMaxSubArray(int* array, int low, int high)
{
Tuple left, right, cross;
// blah blah
if (something)
return left;
else
return right;
}
答案 2 :(得分:0)
所有指针(左,右和交叉)将始终指向&amp; tuple的相同内存位置。如果你想要不同的元组,你需要使用malloc在堆上创建不同的元组攻击。