我正在学习C语言,并试图解决LeetCode的练习412.

我的问题是,当x127时,当执行代码的第64行时,x返回到124值,程序进入无限循环.

第64行

output = realloc(output, sizeof(char *) * x);

我的整个代码:

#include <stdio.h>
#include <stdlib.h>

char **fizzBuzz(int n) {
    int x, temp, x_aux, cont;
    char **output;
    output = NULL;
    for (x = 1; x <= n; x++)
    {
        if (x % 3 == 0)
        {
            if (x % 5 == 0)
            {
                //answer[i] == "FizzBuzz" if i is divisible by 3 and 5.
                output = realloc(output, sizeof(char *) * x);
                output[x-1] = malloc(sizeof(char) * 9);
                output[x-1][0] = 'F';
                output[x-1][1] = 'i';
                output[x-1][2] = 'z';
                output[x-1][3] = 'z';
                output[x-1][4] = 'B';
                output[x-1][5] = 'u';
                output[x-1][6] = 'z';
                output[x-1][7] = 'z';
                output[x-1][8] = 0;
            }
            else
            {
                //answer[i] == "Fizz" if i is divisible by 3.
                output = realloc(output, sizeof(char *) * x);
                output[x-1] = malloc(sizeof(char) * 5);
                output[x-1][0] = 'F';
                output[x-1][1] = 'i';
                output[x-1][2] = 'z';
                output[x-1][3] = 'z';
                output[x-1][4] = 0;
            }
        }
        else if (x % 5 == 0)
        {
            //answer[i] == "Buzz" if i is divisible by 5.
            output = realloc(output, sizeof(char *) * x);
            output[x-1] = malloc(sizeof(char) * 5);
            output[x-1][0] = 'B';
            output[x-1][1] = 'u';
            output[x-1][2] = 'z';
            output[x-1][3] = 'z';
            output[x-1][4] = 0;
        }
        else
        {
            //answer[i] == i (as a string) if none of the above conditions are true.
            output = realloc(output, sizeof(char *) * x);
            cont = 1;
            x_aux = x;
            while (x_aux >= 10)
            {
                temp = x_aux % 10;
                output[x-1] = realloc(output[x-1], sizeof(char) * cont);
                output[x-1][cont-1] = temp + '0';
                x_aux = (int)x_aux / 10;
                cont += 1;
            }
            output[x-1] = realloc(output[x-1], sizeof(char) * (cont+1));
            output[x-1][cont-1] = x_aux + '0';
            output[x-1][cont] = 0;
        }
    }
    return output;
}

int main()
{
    char **string;
    int num = 134;
    int m, y;
    string = fizzBuzz(num);

    for (m = 0; m < num; m++)
    {
        for (y = 0; string[m][y] != 0; y++)
            printf("%c", (char)string[m][y]);
        printf("\n");
    }

    return 0;
}

谢谢!!

我知道解决方案的逻辑不是x%正确的,但我想知道x更改值(127124)会发生什么.

推荐答案

该代码具有未定义的行为:在regular个数字的情况下,既不能被3整除也不能被5整除,您使用output = realloc(output, sizeof(char *) * x)重新分配数组,这不会初始化output[x-1],并且您在循环之前没有将此指针设置为NULL,在循环中您以10为基数构造数字. 线

output[x-1] = realloc(output[x-1], sizeof(char) * cont);

将一个未初始化的指针传递给realloc,调用未定义的行为. 未定义的行为意味着任何事情都可能发生.

您可以通过在此realloc调用后设置output[x-1] = NULL;来解决此问题.

另请注意这些备注:

  • regular个数字的数字是以相反的顺序构建的,main中的循环不会纠正这一点.
  • output指向的数组应该分配给对malloccalloc的单个调用,而不需要realloc
  • 应测试并报告内存分配错误
  • 对于strdup(),分配"Fizz""Buzz""FizzBuzz"字符串的副本会简单得多.
  • 对于snprintfstrdup,为常规数字分配字符串很容易.
  • 输出的字符串应该为printf("%s\n", string[m]),不需要嵌套循环.
  • 应释放已分配的对象

以下是一个简化版本:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char **fizzBuzz(int n) {
    char **output = calloc(sizeof(*output), n);
    if (output == NULL)
        return NULL;
    for (int x = 1; x <= n; x++) {
        if (x % 3 == 0) {
            if (x % 5 == 0) {
                output[x - 1] = strdup("FizzBuzz");
            } else {
                output[x - 1] = strdup("Fizz");
            }
        } else
        if (x % 5 == 0) {
            output[x - 1] = strdup("Buzz");
        } else {
            char buf[20];
            snprintf(buf, sizeof buf, "%d", x);
            output[x - 1] = strdup(buf);
        }
    }
    return output;
}

int main(void) {
    int num = 134;
    char **vector = fizzBuzz(num);
    if (vector) {
        for (int m = 0; m < num; m++) {
            printf("%s\n", vector[m]);
            free(vector[m]);
        }
        free(vector);
    }
    return 0;
}

一旦您掌握了条件运算符,您就可以使用这个更紧凑的版本:

char **fizzBuzz(int n) {
    char **output = calloc(sizeof(*output), n);
    if (output) {
        for (int x = 1; x <= n; x++) {
            char buf[32];
            snprintf(buf, sizeof buf, "%d", x);
            output[x - 1] = strdup(x % 15 == 0 ? "FizzBuzz" :
                                   x % 3 == 0 ? "Fizz" :
                                   x % 5 == 0 ? "Buzz" : buf);
        }
    }
    return output;
}

C++相关问答推荐

为什么listen()(在调用accept()之前)足以让应用程序完成3次握手?

使用单个字节内的位字段

使用额外的公共参数自定义printf

ESP32在vTaskDelay上崩溃

将uintptr_t添加到指针是否对称?

FRIDA-服务器成为端口扫描的目标?

我的C函数起作用了,但我不确定为什么

如何在C++中安全地进行浮点运算

如何使用libgpio(d)为Raspberry Pi编译C程序?

Tic-tac-toe:从文件加载存储

将回调/基于事件的C API转换为非回调API

循环中的静态变量与块中的变量和循环

通过对一个大的Malloc内存进行切片来使用Malloc的内存片

在吉陀罗中,_2_1_和CONCAT11是什么意思?

在C中打印指针本身

在C中,为什么这个带有递增整数的main函数从不因溢出而崩溃?

C struct 中的冒泡排序

在 C 中传递参数时出现整数溢出

从管道读取数据时丢失

初始化动态分配的布尔二维数组的最佳方法是什么?