【问题标题】:Struct pointer becomes NULL at every function call [closed]结构指针在每次函数调用时变为 NULL [关闭]
【发布时间】:2019-09-12 08:25:24
【问题描述】:

我遇到了一个关于在 C 上使用 struct 制作“Sets”的问题。

我已经初始化了两个结构指针(S1,S2)。 第一次用 %p 初始化指针和打印地址是有效的,但是在用 S2 访问函数之后,它就不起作用了。 我在访问函数后检查了指针。 S2 的地址变为 NULL。 我不知道我该如何解决这个问题..

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

#define defaultSize 5

typedef enum {FALSE, TRUE} Boolean;

typedef struct {
    int nElements;
    int arraySize;
    char **element;
} strset_t;

strset_t *createSet()
{
    strset_t *s;
    if((s = (strset_t*)malloc(sizeof(strset_t))) != NULL){
        s->element = (char **)malloc(sizeof(char *) * defaultSize);

        s->nElements = 0;
        s->arraySize = defaultSize;
    }

    return s;
}

void deleteSet(strset_t *s)
{
    free(s->element);
    free(s);
}

int cardinality(strset_t *s)
{
    return s->nElements;
}

int isElement(char *x, strset_t *a)
{
    for(int i = 0; i < a->nElements; i++)
        if(strcmp(x, a->element[i]) == 0)
            return i;
    return -1;
}

Boolean addElement(char *x, strset_t *a)
{
    if(a->nElements == a->arraySize){
        a->arraySize *= 2;
        a = realloc(a, a->arraySize);

        puts("== extended ==");
    }

    if(a == NULL){
        puts("=== NULL ===");
        return FALSE;
    }

    a->element[a->nElements] = (char *)malloc(strlen(x) + 1);
    strcpy(a->element[a->nElements], x);
    a->nElements++; //deep copy를 사용하여 값 전달

    return TRUE;
}

Boolean removeElement(char *x, strset_t *a)
{
    int idx = isElement(x, a);

    if(idx == -1){
        puts("=== Not found ===");
        return FALSE;
    }

    for(int i = idx; i < a->nElements - 1; i++){
        free(a->element[i]);
        a->element[i] = a->element[i + 1];
    }

    free(a->element[a->nElements - 1]);
    a->nElements--;
}

int main()
{
    strset_t *S1, *S2;

    S1 = createSet();
    S2 = createSet();

    Boolean run = TRUE;

    char target, selection;
    char buff[100];

    while(run){
        printf("%p %p\n", S1, S2);

        fflush(stdin);

        switch (getchar()) {
        case '1':
            printf("Target(1, 2)) : ");
            scanf("%d", &target);
            fflush(stdin);
            printf("Element : ");
            if(target == 1)
                addElement(gets(buff), S1);
            else if(target == 2)
                addElement(gets(buff), S2);

            break;

        case '2':
            printf("Target(1, 2)) : ");
            scanf("%d", &target);
            fflush(stdin);
            printf("Element : ");
            if(target == 1)
                removeElement(gets(buff), S1);
            else if(target == 2)
                removeElement(gets(buff), S2);

            break;

        case 'X':
            run = FALSE;
            break;

        default:
            puts("== Invalid menu ==");
            getchar();
            break;
        }

        printf("\n");
    }

    deleteSet(S1);
    deleteSet(S2);

    system("pause");
    return 0;
}

【问题讨论】:

  • 一个结构不能变成 NULL。指针可以。
  • @AnttiHaapala 是的,我的意思是,结构指针每次都是 NULL 指针。谢谢,我会修改我的帖子
  • 1) 永远不要使用gets,不再是语言的一部分,而是使用fgets 并去掉结尾的'\0' 2) "%p" 想要一个演员:(void *)S1
  • 你给你的程序什么输入?你怎么知道指针变成空了?在 what? 的每个函数调用之后
  • scanf("%d", &amp;target); - 它需要 inttargetchar

标签: c memory struct


【解决方案1】:

addElement() 中,realloc() 的调用仅获得a-&gt;arraySize 的大小,但您需要sizeof(char *) * a-&gt;arraySize,就像在malloc() 的调用中一样。分配的块将比以前更小(因为sizeof(char *) 大于 1,具体取决于您的系统),并且当写入它时,其他内存将被覆盖。

【讨论】:

  • 哦,我有错误。谢谢!
猜你喜欢
  • 2015-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-13
  • 2013-03-05
  • 1970-01-01
  • 2012-05-17
相关资源
最近更新 更多