【问题标题】:C solution to Leetcode "Two Sums" has runtime errorLeetcode "Two Sums" 的 C 解决方案存在运行时错误
【发布时间】:2015-07-05 14:34:15
【问题描述】:

我刚刚完成了 Leetcode “Two Sums”的 C 解决方案。但是网站说“运行时错误”,没有说哪一行代码是错误的。以下代码在 Xcode 中完美运行。我的代码有什么问题吗?

int* twoSum(int* nums, int numsSize, int target);

int main(int argc, const char * argv[]) {
    int nums[] = { 1, 2, 4, 8, 16};
    int numsSize = 5;
    int target = 10;
    int *answer = twoSum(nums, numsSize, target);

    printf("index1 = %d, index2 = %d\n", answer[0], answer[1]);

    return 0;
}

struct bucketLayer {
    int data;
    int index;
    struct bucketLayer* ptr;
};

struct result {
    int found;
    int index;
};

struct bucketLayer *addData(int data, int index, struct bucketLayer *targetPtr);
struct result findData(int data, int firstIndex, struct bucketLayer *targetPtr);
struct bucketLayer *freeBucket(struct bucketLayer *bucketPtr);

int* twoSum(int* nums, int numsSize, int target) {
    struct bucketLayer *buckets[target];

    int *answer = (int *)malloc(2 * sizeof(int));

    for (int i = 0; i < numsSize; i++) {
        buckets[nums[i] % target] = addData(nums[i], i, buckets[nums[i] % target]);
    }

    for (int i = 0; i < numsSize - 1; i++) {
        struct result findResult = findData(target - nums[i], i, buckets[target - nums[i] % target]);
        if (findResult.found) {
            if (findResult.index > i) {
                answer[0] = i+1;
                answer[1] = findResult.index + 1;
                return answer;
            } else {
                answer[0] = findResult.index + 1;
                answer[1] = i + 1;
                return answer;
            }
        }
    }

    for (int i = 0; i < target; i++) {
        buckets[i] = freeBucket(buckets[i]);
    }

    return answer;
}

struct bucketLayer *addData(int data, int index, struct bucketLayer *targetPtr) {
    if (targetPtr == NULL) {
        targetPtr = (struct bucketLayer *)malloc(sizeof(struct bucketLayer));
        targetPtr->data = data;
        targetPtr->index = index;
        targetPtr->ptr = NULL;
    } else {
        targetPtr->ptr = addData(data, index, targetPtr->ptr);
    }

    return targetPtr;
}

struct result findData(int data, int firstIndex, struct bucketLayer *targetPtr) {
    struct result findResult;
    if (targetPtr == NULL) {
        findResult.found = 0;
        return findResult;
    } else {
        if (targetPtr->data == data && targetPtr->index != firstIndex) {
            findResult.found = 1;
            findResult.index = targetPtr->index;
            return findResult;
        } else {
            return findData(data, firstIndex, targetPtr->ptr);
        }
    }
}

struct bucketLayer *freeBucket(struct bucketLayer *bucketPtr) {
    if (bucketPtr != NULL) {
        bucketPtr->ptr = freeBucket(bucketPtr->ptr);
        free(bucketPtr);
    }
    return bucketPtr;
}

【问题讨论】:

  • TL;DR 这不是代码审查网站。如果你有一个具体的问题,请展示你做了什么。然而,一个提示:undefined behavior 众所周知,在不同的系统上表现不同。我会检查这个。
  • 标准警告:不要像 malloc 返回的那样转换 void *
  • @Olaf 谢谢。你的意思是我应该从 malloc 中删除显式指针转换? K&R C 教科书使用这种风格。即使我删除了显式转换,leetcode.com 仍然给我运行时错误。
  • 猜测:buckets 是一个局部变量,而不是零初始化的。所以addData 中的targetPtr 是垃圾,针对NULL 进行测试是没有意义的。
  • @deniss 非常感谢!你是对的,在我的 Xcode 中,指针自动初始化为零,但 Leetcode.com 似乎使用 gcc。

标签: c runtime-error


【解决方案1】:

仔细查看代码后,问题是通过使用指向struct bucketLayer的指针的可变长度数组引入的。在这种情况下,虽然有一个可用的静态指针,但指针未初始化并导致addData 函数错误地处理指针。只需手动初始化:

struct bucketLayer *buckets[target];

for (int i = 0; i < target; i++)
    buckets[i] = NULL;

int *answer = malloc (2 * sizeof *answer);

for (int i = 0; i < numsSize; i++) {
    buckets[nums[i] % target] = addData(nums[i], i, buckets[nums[i] % target]);
}

addData 分配也可以简化为:

 targetPtr = malloc (sizeof *targetPtr);

【讨论】:

  • @DavidC.Rankin 谢谢。顺便说一句,如果在声明后分配存储桶,我的 addData() 将不起作用。 addDatda() 完成检查和分配内存的工作:)
猜你喜欢
  • 1970-01-01
  • 2012-05-08
  • 2020-04-22
  • 1970-01-01
  • 2021-11-03
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多