不能malloc然后转到程序顶部

时间:2015-11-26 00:13:40

标签: c malloc goto

在这工作了好几个小时。我一直都很难过。

这是CS113的实验室。

如果用户在程序结束时(二进制计算器)选择继续,我们需要使用goto语句来到程序的顶部。

但是,我们还需要释放所有已分配的内存。

这两件事似乎不相容。如果我释放分配的内存并且用户选择继续,那么一切都绝对是疯狂的。即使这些值被重新初始化,也会在某种程度上搞砸了。我真的很抱歉,但我不知道如何更好地解释它。看起来他们最终会被垃圾填满,尽管这些步骤与第一次运行相同。

我的代码如下。请注意,“免费分配的内存”部分在我的版本中已注释掉,但我把它留在这里,所以不会有混淆。

编辑:现在可以释放CPU。目前的版本,它的作用。但是,我无法释放我分配的字符串,或者由双链表组成的寄存器。我不能使用的免费功能被注释掉,并且在程序结束时。

注意:如果内存在最后没有运行,程序将完全精细,即使多次运行也是如此。请注意这一点。

#include<stdio.h>
#include<stdlib.h>
#include<string.h> 
#include"lab9.h"
#include<math.h>

int main()
{
    struct cpu_t *cpu = NULL;

    top: 

    if(cpu)
    {
        free(cpu);
        cpu = NULL;
    }

    cpu = malloc(sizeof(struct cpu_t));

    if(!cpu) /* Error check malloc for CPU */
        {
                printf("Sorry! Malloc failed to allocate space for the CPU!\n");
                exit(EXIT_FAILURE);
        }  

    struct bit_t *temp1 = cpu->r1_head;
    struct bit_t *temp2 = cpu->r2_head;
    struct bit_t *temp3 = cpu->r3_head; 

    /* Setting all flags to 0 by default */
    cpu->overflow = 0;
    cpu->carry = 0;
    cpu->sign = 0;
    cpu->parity = 0;
    cpu->zero = 0;

    char buffer[128];
    char unsign; /* Holds a char: 0 for signed, 1 for unsigned */
    char *expression = NULL; /* Binary expression */
    char *e1 = NULL; /* Holds the first part of the expression */
    char op; /* Holds the operand */
    char *e2 = NULL; /* Holds the second part of the expression */
    char ans; /* y if user wants to continue, else ends program */
    int temp = 0; /* Used for printing separating dashes */
    int one_count = 0; /* Number of ones in the result */  

        printf("\nPlease enter the word size: ");
    fgets(buffer, sizeof(buffer), stdin);
        cpu->word_size = atoi(buffer); /* atoi takes a pointer, don't dereference buffer*/

        while(cpu->word_size < 1 || cpu->word_size > 64) /* Error check word size */
        {
                printf("Error: Word size must be between 1 and 64. \n");
                printf("Enter a new word size: \n");
        fgets(buffer, sizeof(buffer), stdin);
                cpu->word_size = atoi(buffer);
        }

        printf("Are the values unsigned? [Y/N]: ");

        unsign = *fgets(buffer, sizeof(buffer), stdin); /* fgets returns address to data, must be dereferenced */

    switch(unsign)
    {
    case 'y':
    case 'Y':
        cpu->unsign = 1;    
        break;
    case 'n':
    case 'N':
        cpu->unsign = 0;
        break;
    }

        printf("Please enter the binary expression: ");

    expression = fgets(buffer, sizeof(buffer), stdin); /* Stores expression in string */

    e1 = strtok(expression, " "); /* Breaks off first number*/

    switch(check_string(cpu, e1)) /* Error check first string */
    {
    case 1:
        printf("Error in input: Length of operand greater than word size. \n");
        printf("Error in first operand. Retry. \n");
        goto top;
    case 2:
        printf("Error in input: Something other than a 1 or 0 entered. \n");
        printf("Error in first operand. Retry. \n");
        goto top;
    default:
        break;
    }

    e1 = zero_pad(cpu, e1); /* Zero pads first number */

    op = *strtok(NULL, " "); /* Operation (+, -, ^, &, |) */

    e2 = strtok(NULL, " \n"); /* Original string had \n at end. Otherwise length would be 1 over actual. */

    switch(check_string(cpu, e2)) /* Error check second string */
    {
    case 1:
        printf("Error in input: Length of operand greater than word size. \n");
        printf("Error in second operand. Retry. \n");
        goto top;
    case 2:
        printf("Error in input: Something other than a 1 or 0 entered. \n");
        printf("Error in second operand. Retry. \n");
        goto top;
    default:
        break;
    }

    e2 = zero_pad(cpu, e2); /* Zero pads second number */

    create_r1(cpu, e1);
    create_r2(cpu, e2);
    create_r3(cpu);

    switch(op)
    {
    case '+':
        add_function(cpu);
        break;
    case '-':
        op = '+';
        complement(cpu); /* Turns second expression into 2's complement of itself */
        add_function(cpu);
        break;
    case '&':
        and_function(cpu);
        break;
    case '|':
        or_function(cpu);
        break;
    case '^':
        xor_function(cpu);
        break;
    default:
        printf("Error in operator. Please retry. \n");
        goto top;
    }

    temp1 = cpu->r1_head;
    temp2 = cpu->r2_head;
    temp3 = cpu->r3_head;   

    /* Print the first register */
    while(temp1)
    {
        printf("%d", temp1->n);
        temp1 = temp1->next;
    }
    puts("");

    /* Print operator */
    printf("%c\n", op);

    /* Print second register */
    while(temp2)
    {
        printf("%d", temp2->n);
        temp2 = temp2->next;
    }
    puts("");

    /* Print spacing dashes */
    while(temp < (cpu->word_size))
    {
        printf("-");
        temp++;
    }
    puts("");

    /* Print third register (stores answer) */
    while(temp3)
    {
        printf("%d", temp3->n);
        temp3 = temp3->next;
    }
    puts("");

    /* Flag handling */

    /* Reset temp variables */
    temp1 = cpu->r1_head;
    temp2 = cpu->r2_head;
    temp3 = cpu->r3_head;   

    /* Flag handling */
    if(temp3->n == 1)
    {
        cpu->sign = 1;
    }

    while(temp3)
    {
        if(temp3->n == 1)
        {
            one_count++;
        }
        temp3 = temp3->next;
    }

    if(one_count == 0)
    {
        cpu->zero = 1;
    }
    else if(one_count % 2 == 0)
    {
        cpu->parity = 1;
    }

    printf("Flags: \n");
    printf("Overflow:         %d \n", cpu->overflow);
    printf("Carry:            %d \n", cpu->carry);
    printf("Sign:             %d \n", cpu->sign);
    printf("Parity:           %d \n", cpu->parity);
    printf("Zero:             %d \n", cpu->zero);
    printf("Decimal:      %d \n", find_decimal(cpu));

    printf("Do you want to continue? [Y/N] \n"); /* If not 'y' or 'Y', close program */
    ans = *fgets(buffer, sizeof(buffer), stdin);

    /* Reset temps...again */
    temp1 = cpu->r1_head;
    temp2 = cpu->r2_head;
    temp3 = cpu->r3_head;   

    /* Free all allocated memory */
    //delete_list(cpu->r1_head);
    //delete_list(cpu->r2_head);
    //delete_list(cpu->r3_head);

    /* Free zero_string */
    //free(e1);
    //free(e2);

    if(ans == 'Y' || ans == 'y')
    {
        temp = 0;
        goto top;
    }

        return 0;
}

1 个答案:

答案 0 :(得分:0)

也许你可以将main的开头改为这样的东西:

int main() {
    struct cpu_t *cpu = NULL;
top:
    if (cpu) {
        free(cpu);
        cpu = NULL;
    }
    cpu = malloc(sizeof(struct cpu_t));