【问题标题】:Simplifying macro in C function (dynamically allocated array and MPI_Recv)简化 C 函数中的宏(动态分配的数组和 MPI_Recv)
【发布时间】:2016-01-19 20:33:08
【问题描述】:

我有一个 C 函数(my_malloc 只是一个包装器,用于测试分配是否成功):

#define MAXIMUM {                   \
    int value = 0;                  \
    for (int i = 0; i < n; i++) {   \
        if (value < (*numbers)[i]) {\
            value = (*numbers)[i];  \
        }                           \
    }                               \
    return value;                   \
}

int maximum1(int n, int **numbers) MAXIMUM;

int maximum2(int n, int (*numbers)[n]) MAXIMUM;

然后我这样称呼它(n 在数组中的一些元素中):

int *numbers = my_malloc(n * sizeof(int *));
// array numbers is filled
int value = maximum1(n, &numbers);

int numbers[n];
// array numbers is filled
int value = maximum2(n, &numbers);

可以用它做些什么来让它更干净吗?我只想拥有一个最大功能。

所有问题都从这里开始:

int numbers[n]; 
//int *numbers = my_malloc(n * sizeof(int *)); 
// There is no way, I could find, to use dynamically allocated array...
// the pointer of numbers array changes after calling MPI_Recv...
// only a fixed array worked here, otherwise exactly two  
// elements are received all the time...meh 

//printf("address before: %p\n", numbers); 
MPI_Recv(numbers, n, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); 
//printf("address after: %p\n", numbers); //<-- changing when using malloc
value = maximum2(n, &numbers);


// Copying contents of the static array to dynamically allocated 
// one works (just maximum1 is required)
//int *numbers = my_malloc(n * sizeof(int *)); 
//for (i = 0; i < n; i++)  
    //numbers[i] = numbers_old[i]; 
//value = maximum1(n, &numbers);

未注释的是当前工作状态。 cmets 提出了两种可行的解决方案:

  1. 创建固定数组并将其内容复制到动态分配的数组(此时只需要一个最大功能,但这是一个愚蠢的解决方案)
  2. 仅使用具有 maximum2 功能的固定数组

编辑

经过数小时的头痛后,它确实神奇地似乎正常工作,没有明显的变化,所以我不确定发生了什么......

my_malloc 函数:

void *my_malloc(size_t size) {
    void *p = malloc(size);
    if (p == NULL) {
        printf("Memory allocation unsuccessful.\n");
        exit(EXIT_FAILURE);
    }   
    return p;
}

【问题讨论】:

  • sizeof(int *) 可能与 sizeof(int) 不一样?我认为 MPI_INT 会期望 n*sizeof(int)。
  • Helo @haraldkl,我认为是一样的。我已经花了几个小时解决这个问题,但现在看起来它可以双向工作......有或没有星号。很奇怪。

标签: c mpi


【解决方案1】:

首先,您的内存分配有问题:假设 my_malloc() 只是,正如您所说,“一个用于测试分配是否成功的包装器”,那么您会期望像 int *numbers = my_malloc(n * sizeof(int)); 那样的东西,而不是像 @ 987654325@。前者是正确的,而后者只能(不)幸运地只在sizeof(int) == sizeof(int*) 的机器上工作。我感觉你所有的问题都源于此。

那我不明白你为什么要创建这个繁琐的MAXIMUM 宏和两个不同的函数maximum1()maximum2。这个单一的功能会有什么问题?

int maximum(int n, int *numbers) {
    int value = 0;
    for (int i = 0; i < n; i++) {
        if (value < numbers[i]) {
            value = numbers[i];
        }
    }
    return value;
}

这应该可以正常工作,numbers 应该是动态分配还是静态分配。

尝试修复这些问题,您将在获得更可靠的代码方面取得进展。


编辑:我忘了说这个新的maximum() 函数应该这样调用:

int numbers[n]; // works also with: int *numbers = my_malloc(n * sizeof(int));
int value = maximum(n, numbers);

【讨论】:

  • 您好,我在原帖中添加了my_malloc函数。你可以看到里面没有多少。问题是,您提出的函数需要输入 int *numbers 我的调用都不匹配。它现在仍然对我有用,所以我投票赞成关闭。
  • @delmadord 确实,其中没有太多内容。但这证实了它应该用sizeof(int) 而不是sizeof(int*) 调用。如果你不明白为什么这是不同的,也不知道为什么maximum() 的提议版本可以使用动态或静态内存分配,而且如果你对学习它不感兴趣,那么当然,继续删除你的问题.
  • 如果我将sizeof(int *) 更改为sizeof(int),它不会改变输出,这意味着int 的大小与int 的指针大小相同,正如有人指出的那样,如果我理解正确。问题是它开始工作了,我无法破译,即使从以前的提交中,我做了什么改变以使其工作。
  • 这看起来有点像代码中的一个潜在错误:看起来它可以工作,但这只是偶然......在其他地方更改看似完全不相关的东西可能会突然使其失败。因此,我鼓励您在编译器级别切换尽可能多的调试信息,并通过内存调试器运行代码。如果在 Linux 上,valgrind 可以很好地跟踪内存错误。
  • 谢谢,编辑帮助了,现在可以了。正如您和@heraldkl 建议的那样,我已经从 sizeof 中删除了星号。我会更多地研究这个主题,最初是从book
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 2014-08-19
  • 2021-01-26
  • 1970-01-01
  • 2013-10-31
  • 2021-11-24
相关资源
最近更新 更多