我的 codewars 解决方案在 Visual Studio 中本地运行良好,但在通过 codewars 端的测试时会导致错误

My codewars solution works fine locally in Visual Studio, but causes an error when passing tests on codewars' side

!!!包含 CODEWARS 任务的剧透!!!

给定以下任务

我想到了以下解决方案:

Pair** removNb(long long n, int* length)
{
    int idx = 0;
    Pair* pairs = malloc(0);

    for (long long i = 1; i <= n; i += 1)
    {
        for (long long j = 1; j <= n; j += 1)
        {
            long long product = i * j;
            long long sum = 0;
            for (long long g = 1; g <= n; g += 1)
            {
                if (g != i && g != j)
                {
                    sum += g;
                }    
            }

            if (product == sum)
            {
                pairs = realloc(pairs, (idx + 1) * sizeof(Pair));
                pairs[idx].first = i;
                pairs[idx].snd = j;
                idx += 1;
            }
        }
    }

    *length = idx;
    return &pairs;
}

并在 Visual Studio 中对其进行了本地测试,一切似乎都运行良好(即使我收到了一些关于内存重新分配的警告,但我是 C 语言的新手,目前正在尝试让事情正常工作. 对此的任何建议也很感激 tho)

但是当我尝试在 CodeWars 中测试这个解决方案时,我得到以下提示:

他们似乎使用 Criterion 库来测试解决方案。这是那里的测试代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <criterion/criterion.h>

typedef struct Pair Pair;
struct Pair {
    long long first;
    long long snd;
};

Pair** removNb(long long n, int* length);
// fct  to compare results; sz number of pairs / Pair** arr will be freed
char* array2StringData(Pair** arr, int sz);

void dotest(long long n, char* sexpr) {
    int lg = 0;
    Pair** act = removNb(n, &lg);
    char* sact = array2StringData(act, lg);
    if(strcmp(sact, sexpr) != 0)
        printf("Error. Expected %s but got %s\n", sexpr, sact);
    cr_assert_str_eq(sact, sexpr, "");
    if (strcmp(sact, "{}") != 0) {
        free(sact); sact = NULL;
    }
}

Test(removNb, ShouldPassAllTheTestsProvided) {
    dotest(26, "{{15, 21}{21, 15}}");
    dotest(100 , "{}");
    dotest(37 , "{{21, 31}{31, 21}}");
    dotest(101 , "{{55, 91}{91, 55}}");
}

这个任务让我有点困惑,因为函数应该 return 指向指向结构数组的指针的指针......对我来说,这似乎是一个过多的指针。 那么,是不是测试代码有问题?我有点难以完全理解它...... 还是我的解决方案实际上实施不当?如果是这样,我可以更改什么才不会导致内存错误?

这里不需要指向指针的指针。您正在返回局部变量的地址而不是分配的指针。

Pair* removNb(long long n, int* length)
{
    Pair* pairs = malloc(0);
    ....
    return pairs;
}

如果你需要指针指向指针,那么你也必须为它提供一些内存。

Pair** removNb(long long n, int* length)
{
    Pair** rc = malloc(sizeof(Pair**));
    Pair* pairs = malloc(0);
    ....

    *rc = pairs;
    return rc;
}

哦该死,找到解决方案了。造成该问题的原因是我试图为整个结构数组分配内存。但是在任务描述的最后是这样写的:

in C: removNb(26) should return {{15, 21}{21, 15}} tested by way of strings. Function removNb should return a pointer to an allocated array of Pair pointers, each one also allocated.

因此,所有需要做的就是在每次创建结构时为它分配内存,并将指向该结构的指针推送到指向结构的指针数组...呃O_o

目前解决方案:

typedef struct {
    long long first;
    long long snd;
} Pair;
// fill length with the number of pairs in your array of pairs
Pair** removNb(long long n, int* length) 
{
    int idx = 0;
    Pair** res = NULL;

    for (long long i = 1; i <= n; i += 1)
    {
        for (long long j = 1; j <= n; j += 1)
        {
            long long product = i * j;
            long long sum = 0;
            for (long long g = 1; g <= n; g += 1)
            {
                if (g != i && g != j)
                {
                    sum += g;
                }    
            }

            if (product == sum)
            {
                Pair *pair = malloc(sizeof(Pair));
                pair->first = i;
                pair->snd = j;
                res = realloc(res, sizeof(Pair*) * (idx + 1));
                res[idx] = pair;
                idx += 1;
            }
        }
    }

    *length = idx;
    return res;
}

由于未优化并导致超时,它仍然没有通过所有测试,但这是另一个问题。我现在正在解决它:)