我正在学习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++相关问答推荐

有没有可能我不能打印?(C,流程)

如何在C中使printf不刷新标准输出?

如何将常量char*复制到char数组

SSH会话出现意外状态

为什么将函数名括在括号中会禁用隐式声明?

在创建动态泛型数组时,通过realloc对故障进行分段

为什么指针运算会产生错误的结果?

如何在C中使数组变量的值为常量?

处理来自浏览器的HTTP请求

使用nmake for程序比Hello World稍微复杂一些

如何确保我将使用C标准库函数的函数版本,如&getc";,而不是类似函数的宏版本?

当读取可能会阻塞管道中的父进程时,为什么要等待子进程?

在NASM中链接Linux共享库时出错-';将R_ X86_64_;foo';

如何为avr atmega32微控制器构建C代码,通过光电二极管捕获光强度并通过串行通信传输数据

SSE 向量与 Epsilon 的比较

段错误try 访问静态字符串,但仅有时取决于构建环境

strided memcpy(3) 在 libvpx 中如何工作

C 编译器编写中register关键字的用处

为什么C中的gethostname函数会导致清除路径环境变量?

为什么gcc需要未使用的_Generic值的定义?