指针对象的指针和内存分配

时间:2011-08-30 03:25:12

标签: c++

我一直在用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;

}

3 个答案:

答案 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的地址。在另一个分支中,您将leftrightcross设置为findMaxCrossingSubArrayfindMaxSubArray,它们都以&tuple单向返回,或者另一个。

我建议你阅读一本关于C ++的书,并在使用C ++时忘记你所知道的关于C的所有内容(但是当你再次编程C时,请记住这一切)。它们不是同一种语言。这段代码充斥着您从C培训中学到的东西(例如#definetypedef struct ... Tuple),C ++提供了更好的设施。

答案 1 :(得分:1)

实际分配的唯一Tuple是全局范围内的tuple。所有指向Tuple的指针,例如Tuple* left只是指向全局存储。例如在:

 left = findMaxSubArray(array, low, mid);
 right = findMaxSubArray(array, mid + 1, high);

您会发现leftright都指向同一地址,因此指向相同的值。

如果没有详细说明,并注意到这是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在堆上创建不同的元组攻击。