代码之家  ›  专栏  ›  技术社区  ›  ParthJha17

当我试图学习使用realloc和malloc时,n的值设置为0或1(未定义的行为)

  •  1
  • ParthJha17  · 技术社区  · 2 年前

    我正在编写一个C程序,为一个动态字符串数组创建一个交互式界面。该程序由菜单驱动,并遵循以下步骤:

    1. 询问用户数组的初始长度。
    2. 将相应的字符串存储到用该长度初始化的动态数组中。
    3. 启动菜单循环,提示用户选择五个选项之一: (a) 将字符串添加到数组的末尾, (b) 在数组的开头添加一个字符串, (c) 删除数组索引'x'处的元素(作为输入), (d) 显示阵列的长度, (e) 按顺序显示数组的所有元素。
    4. 添加和删除字符串会导致数组的大小调整。
    5. 提供第六个选项以关闭菜单驱动的程序,从而终止循环。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #include <stdlib.h>
    
    typedef struct UserStrings
    {
        char in[100];
    } input;
    
    int main(void)
    {
    
        int n;
        printf("Enter size of Array, please: \n");
        scanf(" %d", &n);
        input *names = (input *)malloc(n * sizeof(input));
    
        for (int i = 0; i < n; ++i)
        {
            printf("Enter String Number %d : ", i + 1);
            scanf("%s", names[i].in);
        }
    
        printf("%d\n",n);
        char temp = ' ';
    
        while (temp != 'f')
        {
            printf("Enter -a- to add an element at the end of the array\n"
                   "Enter -b- to add a string at the beginning of the array\n"
                   "Enter -c- to delete an element at an index\n"
                   "Enter -d- to display the length of the array\n"
                   "Enter -e- to display all elements\n"
                   "Enter -f- to terminate this program\n");
    
            scanf("%s", &temp);
    
            if (temp == 'a')
            {
                names = (input *)realloc(names, (n + 1)*sizeof(input));
                printf("Enter the string\n");
                scanf("%s", names[n].in);
                ++n;
                printf("%d\n",n);
            }
            else if (temp == 'b')
            {
                names = (input *)realloc(names, (n + 1)*sizeof(input));
                ++n;
                printf("Enter the string\n");
    
                for (int i = n - 1; i > 0; --i)
                {
                    strcpy(names[i].in, names[i - 1].in);
                }
                scanf("%s", names[0].in);
                printf("%d\n",n);
            }
    
            else if (temp == 'c')
            {
                printf("Enter the index 0-%d: ", n - 1);
                int ind;
                scanf(" %d", &ind);
    
                if (ind < 0 || ind >= n)
                {
                    printf("Invalid index. Please enter a valid index.\n");
                    continue; // Skip the rest of the loop iteration
                }
    
                input *new = (input *)malloc((n - 1) * sizeof(input));
    
                int flag = 0;
                for (int i = 0; i < n; ++i)
                {
                    if (i == ind)
                    {
                        flag = 1;
                        continue; // Skip the element at the specified index
                    }
    
                    new[i - flag] = names[i];
                }
                free(names);
                names = new;
                new = NULL;
                --n;
                printf("%d\n",n);
            }
            else if (temp == 'd')
            {
                printf("Lenght of the array is %d\n", n);
            }
            else if (temp == 'e')
            {
                for (int i = 0; i < n; ++i)
                {
                    printf("%d is : %s \n", i + 1, names[i].in);
                }
            }
            else if (temp == 'f')
            {
                printf("Program terminated!\n");
                return 1;
            }
            else
                printf("PLEASE ENTER IN SMALL CAPS AND CORRECT INPUT\n");
        }
    }
    
    

    我尝试使用printf语句调试代码,其中丢失了n的值。在初始化数组时,它似乎具有预期值。但当我尝试ANY操作后,n的值发生了意外的变化。这是输出。

    请帮帮我。

    Enter size of Array, please:
    2
    Enter String Number 1 : A
    Enter String Number 2 : B
    2 // This is the output of printf. So n is fine here.
    Enter -a- to add an element at the end of the array
    Enter -b- to add a string at the beginning of the array
    Enter -c- to delete an element at an index
    Enter -d- to display the length of the array
    Enter -e- to display all elements
    Enter -f- to terminate this program
    e // No elements are printing.
    Enter -a- to add an element at the end of the array
    Enter -b- to add a string at the beginning of the array
    Enter -c- to delete an element at an index
    Enter -d- to display the length of the array
    Enter -e- to display all elements
    Enter -f- to terminate this program
    d
    Lenght of the array is 0 /* Length of array is 0? In the whole code, I cant spot why n will change using these operations. */
    
    1 回复  |  直到 2 年前
        1
  •  1
  •   John Omielan    2 年前

    出现问题的一个可能原因是溢出。特别是,您定义了

    char temp = ' ';
    

    但随后使用为其获取新值

    scanf("%s", &temp);
    

    这读起来是 一串 ,不是一个字符,所以即使是一个字符串也会将2个字节读入的位置 temp 然而,它只有1个字节,因此堆栈上的下一个字节将被覆盖,这显然是您的声明 n 即。,

    int n;
    

    然而,即使这不是具体原因,它仍然会导致UB(未定义的行为)。一个简单的解决方案是使用 %c 而不是 %s 在里面 scanf 即。,

    scanf("%c", &temp);
    

    如果此更改修复了问题,那么我确定的这个问题很可能是导致问题的原因。我没有立即发现您的代码有任何其他问题,特别是可能导致您看到的问题发生的问题。

    推荐文章