I have been struggling with pointer and memory allocation in c for a while.
Here’s my implementation for the max subarray problem. It seems to work fine (maybe have bugs). But I have a question about the memory storage for tuple struct object. As you can see, tuple is declared in the global storage. Later in the findMaxSubArray() function, three pointers to Tuple struct are declared. My question is we didn’t declare Tuple struct object instances that the pointers (left, right, cross) are addressing how come the pointer dereferences (i.e., left->sum, etc) work. Does the GNU c compiler automatically allocate storage for them? (I don’t understand x86 assembly code) Can someone please explain what’s going on here? Much appreciated.
#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;
}
The global variable
tupleis the only actualTuplein this program. Memory for global variables is managed by the compiler.In
main,Tuple *resultis just a pointer which, when you declared it, contains a random number (whatever happened to previously be in the space it now occupies) and thusresultpoints to garbage (not a validTupleobject).Then you assign the result of
findMaxSubArraytotuple. SincefindMaxSubArrayreturns&tuple(in one way or another) which is a global variable,resultpoints to the global variabletuple. So when you doresult->sum, it’s the same as doingtuple.sum.In
findMaxSubArray, the lineTuple *left, *right, *cross;declares three pointers toTuples which contain a garbage value. In one branch of theifyou don’t use them and just return&tuple, the address of the global variabletuple. In the other branch, you setleft,right, andcrossto eitherfindMaxCrossingSubArrayorfindMaxSubArray, which both return&tupleone way or the other.I do suggest reading a book on C++ and forgetting everything you know about C while using C++ (but remember it all again when you program C again). They are not the same language. This code is riddled with things you learned from your C training (such as
#defineandtypedef struct ... Tuple) for which C++ offers better facilities.