简体   繁体   English

结构成员在通过后已损坏,但在再次通过后未损坏

[英]Struct member corrupted after passed but not after passed again

I'm having some very strange bug in my ANSI C program. 我的ANSI C程序中有一个非常奇怪的错误。 I'm using debugger and I've observed that 'size' variable is corrupted in function 'doSthing.' 我正在使用调试器,并且观察到函数“ doSthing”中的“ size”变量已损坏。 Outside of 'doSthing' 'size' got a proper value, but inside 'doSthing' I've got a value nothing similar to what it should be, possibly some random data. 在“ doSthing”之外,“大小”有一个适当的值,但是在“ doSthing”中,我有一个与应有的值完全不同的值,可能是一些随机数据。 This would be not be such a mystery but... 这不是一个谜,但是...

In 'doAnotherThing' which is called from 'doSthing' I get the proper value again. 在从“ doSthing”调用的“ doAnotherThing”中,我再次获得了正确的值。 I suppose if it passes the correct value, it is not corrupted anyway, am I wrong? 我想如果它传递正确的值,那么它无论如何都不会损坏,我错了吗? But then why does it have a different value? 但是,为什么它具有不同的价值?

The pointer in struct does not change inside the functions. struct中的指针在函数内部不变。 Memory is allocated for both oTV and oTV->oT . oTVoTV->oT分配了内存。

I really don't see what's happening here... 我真的不知道这里发生了什么...

typedef struct{
ownType     *oT[]   /* array of pointers */
int     size;
} ownTypeVector;

void doSthing(ownTypeVector* oTV);
void doAnotherThing(ownTypeVector* oTV);


void doSthing(ownTypeVector* oTV)
{

...
    doAnotherThing(oTV);
...

}

Thanks for your comments, I collected all the code that contains control logic and data structures so that it compiles. 感谢您的评论,我收集了包含控制逻辑和数据结构的所有代码,以便对其进行编译。 It runs on in an embedded systems, that can receive characters from multiple sources, builds strings from it by given rules and after the strings are ready, calls a function that needs that string. 它在嵌入式系统上运行,可以从多个来源接收字符,并根据给定的规则从中构建字符串,并在字符串准备好后调用需要该字符串的函数。 This can also be a list of functions. 这也可以是功能列表。 This is why I have function pointers - I can use the same logic for a bunch of things simply by choosing functions outside the 'activityFromCharacters' function. 这就是为什么我有函数指针-我可以通过在'activityFromCharacters'函数之外选择函数来对一堆东西使用相同的逻辑。 Here I build a data structre with them by adding As, Bs and Cs to the AVector. 在这里,我通过将A,B和C添加到AVector来构建它们的数据结构。 Of course every one of these separate sources has their own static strings so that they do not bother each other. 当然,这些单独的源中的每个源都有其自己的静态字符串,因此它们不会彼此打扰。

The problem again in the more detailed version of the code: 在更详细的代码版本中再次出现该问题:

'aV->size' has got a proper value everywhere, except 'handleCaGivenWay.' 除“ handleCaGivenWay”外,“ aV-> size”在每个地方都有适当的值。 Before it gets calles, 'aV->size' is ok, in 'addA' 'aV->size' is ok, too. 在被调用之前,'aV-> size'还可以,在'addA'中'aV-> size'也可以。 After leaving 'handleCaGivenWay' it is ok again. 离开“ handleCaGivenWay”之后,就可以了。

#define                     NUMBER_OF_AS            1
#define                     NUMBER_OF_BS            5
#define                     NUMBER_OF_CS            10

typedef struct{
char    name[81];
} C;

typedef struct{
C               *c[NUMBER_OF_CS];   /* array of pointers */
int                     size;
int                     index;
} B;

typedef struct{
B *b[NUMBER_OF_BS];     /* array of pointers */
char    name[81];
int     size;
} A;

typedef struct{
A *a[NUMBER_OF_AS]; /* array of pointers */
int     size;
} AVector;

typedef struct {
char *string1;
char *string2;
} stringBundle;

typedef struct{
void (*getCharacter)(char *buffer);
void (*doSthingwithC)(stringBundle* strings,AVector* aV);
AVector*    aV;

} functionBundle;

void getCharFromaGivenPort(char *buffer)
{
//...
}

void addA(AVector * aV, stringBundle* strings)
{
            aV->a[aV->size]->size = 0;
            ++aV->size;

                int i = 0;

            if(strlen(strings->string2) < 81)
            {
                for(i;i<81;++i)
                {
                    aV->a[aV->size-1]->name[i] = strings->string2[i];
                }
            }
            else {report("Too long name for A:");
                    report(strings->string2);}
}


void handleCaGivenWay(stringBundle* strings,AVector* aV)
{
    A* a;
    a = NULL;
    if(aV->size) { a = aV->a[aV->size-1]; }

switch(1)
{
    case 1:     addA(aV,strings); break;
    case 2:     //addB()...

    default:                if (a && aV->size)
                                    {   //addC(a->thr[a->size-1],c);
                                    }

                            else report("A or B or C invalid");
                            break;
}
//handleCaGivenWay
}

void activityFromCharacters(stringBundle* strings,functionBundle* funcbundle)
{
        /* some logic making strings from characters by */
        /* looking at certain tokens */

        (* funcbundle->doSthingwithC)(strings,funcbundle->aV);
}
//activityFromCharacters

AVector* initializeAVector(void)
{
AVector* aV;

if (NULL == (aV = calloc(1,sizeof(AVector))))
    { report("Cannot allocate memory for aVector."); }

int i = 0;
int j = 0;
int k = 0;

for(i; i < NUMBER_OF_AS; ++i)
{
    if (NULL == (aV->a[i] = calloc(1,sizeof(A))))
            { report("Cannot allocate memory for As."); }

    aV->a[i]->size = 0;
    aV->a[i]->name[0] = 0;

    for(j; j < NUMBER_OF_BS; ++j)
        {
        if (NULL == (aV->a[i]->b[j] = calloc(1,sizeof(B))))
                        { report("Cannot allocate memory for Bs."); }

        aV->a[i]->b[j]->size = 0;

        for(k; k < NUMBER_OF_CS; ++k)
            {
            if (NULL == (aV->a[i]->b[j]->c[k] = calloc(1,sizeof(C))))
                            { report("Cannot allocate memory for Cs."); }
            }
        }
}

aV->size = 0;

return aV;
//initializeProgramVector
}

int main (void)
{
AVector* aV;
   aV = initializeAVector();


while(1)
{
    static stringBundle string;
        static char str1[81];
        static char str2[81];
        string.string1 = str1;
        string.string2 = str2;

        functionBundle funcbundle;
        funcbundle.getCharacter = &getCharFromaGivenPort;
        funcbundle.doSthingwithC = &handleCaGivenWay;
        funcbundle.aV = aV;

        activityFromCharacters(&string,&funcbundle);
}

//main
}

your code shows that it hasn't any error... But i think you are doing mistake in getting the value of size in doSthing function. 您的代码表明它没有任何错误...但是我认为您在获取doSthing函数的size值时犯了错误。 you are printing there its address. 您正在那里打印其地址。 so concentrate on some pointer stuff.. 所以专注于一些指针的东西。

Try printing the oTV->size just before the call and as the first statement in doSthing function. 尝试在调用之前并作为doSthing函数的第一条语句打印oTV->size If you get the correct value in both print, then the problem is with the function doSthing . 如果两次打印都获得正确的值,则问题出在doSthing函数doSthing Problem could be better understood if you've shown the code that calls doSthing . 如果已经显示了调用doSthing的代码,则可以更好地理解问题。

Searched a long time to find this. 搜索了很长时间才找到这个。 I found 2 problems, but dont know what exactly you are trying to accomplish so i cannot tell for certain that the fix'es i propose are what you intend. 我发现了2个问题,但不知道您到底想完成什么,所以我不能肯定地说我提出的解决方案就是您想要的。

typedef struct{
    A *a[NUMBER_OF_AS]; /* array of pointers */
    int     size;
} AVector;

// and in addA():
aV->a[aV->size]->size = 0;

First: You are inlining the array of pointers in the struct. 第一:您要在结构中内联指针数组。 What i think what you want and need is a pointer to a pointer array so that it can grow which is what you want in addA() i think. 我认为您想要和需要的是一个指向指针数组的指针,以便它可以增长,这就是您在addA()想要的。 The line from addA() aV->a[aV->size]->size = 0; 从addA() aV->a[aV->size]->size = 0;的行aV->a[aV->size]->size = 0; does not communicate your intention very well but it looks like you are trying to change the value beyond the last entry in the array and since it is inlined in the struct it would result to the separate field size by pure coincidence on some alignments; 不能很好地传达您的意图,但是您似乎试图更改数组最后一个条目之外的值,并且由于该值已在结构中内联,因此在某些对齐方式上纯碰巧将导致单独的字段size this is a very fragile way of programming. 这是一种非常脆弱的编程方式。 So what i propose is this. 所以我建议的是这个。 Change the struct to contain A** a; // pointer to pointer-array 将结构更改为包含A** a; // pointer to pointer-array A** a; // pointer to pointer-array , malloc it initially and re-malloc (and copy) it whenever you need it to grow (in addA() ). A** a; // pointer to pointer-array ,最初对其进行malloc分配,并在需要增长时重新对其进行malloc(复制)(在addA() )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM