C:复制一些结构会导致奇怪的行为

时间:2012-08-10 17:51:47

标签: c

我在行中有一个恼人的错误

rq->tickets[rq->usedContracts] = toAdd;

如果我这样做:rq->tickets[0] = toAdd程序崩溃

如果我rq->tickets[1] = toAdd;它可以正常工作

valgrind说

  

== 19501 ==使用大小为8的未初始化值

  

== 19501 ==写入大小为8无效

这条线。有什么问题?

    struct TS_element {
    int travels;
    int originalTravels;
    int cost;
    char** dates;
    int moneyLeft;
} TicketSet;

struct RQ_element {
    int usedContracts;

    struct TS_element* tickets;
} RabQav;



TicketSetStatus tsCreate(TicketSet* t, int n, int c) {
    if (n <= 0)
    return TS_ILLEGAL_PARAMETER;
    TicketSet* myTicketSet = (TicketSet*) malloc(sizeof(TicketSet));
    if (myTicketSet == NULL) {
        return TS_CANNOT_CREATE;
    }
    myTicketSet->usedTravels = 0;
    myTicketSet->originalTravels = n;
    myTicketSet->cost = c;
    myTicketSet->moneyLeft = n * c;
    char**  dates =  malloc(sizeof(char**)* (n)); //todo maybe c99 allows dynamic arrays?
    for (int i = 0; i < n; i++) {
        dates[i] =  malloc(sizeof(char)*GOOD_LENGTH+1);
        if (dates[i] == NULL) {
            free(dates);  
            free(t);
            return TS_CANNOT_CREATE;
        }
    }


    myTicketSet->dates = dates;
    *t = *myTicketSet;

    return TS_SUCCESS;
}


static void copyTicketSets(TicketSet* dest, const TicketSet* source) {

    dest->usedTravels = source->usedTravels;
    dest->originalTravels = source->originalTravels;
    dest->cost = source->cost;
    dest->moneyLeft = source->moneyLeft;

    for (int i = 0; i < source->originalTravels; i++) {
        if (NULL != source->dates[i]) {
            free(dest->dates[i]);
            dest->dates[i] = malloc(sizeof(char) * GOOD_LENGTH + 1);
            if (dest->dates[i] == NULL) {
                free(dest->dates); //todo free dates 0...i-1
                free(dest);
                return;
            }
            strcpy(dest->dates[i], source->dates[i]);
        }

    }

}
RabQavStatus rqLoadTS(RabQav* rq, TicketSet t, DateTime dt) {


    TicketSet toAdd;
    TicketSetStatus res = tsCreate(&toAdd, t.originalTravels, t.cost);
    if (res != TS_SUCCESS) {
        return RQ_FAIL;
    }

    copyTicketSets(&toAdd, &t);  
    rq->tickets[rq->usedContracts] = toAdd;
    rq->usedContracts++;
    return RQ_SUCCESS;

}

1 个答案:

答案 0 :(得分:4)

以下是一些问题:

TicketSetStatus tsCreate(TicketSet* t, int n, int c) {

如何通过tsCreate TicketSet*?它创建票证集。因此,在进入时不知道指向票证集的指针。

*t = *myTicketSet;

这会将t的值设置为myTicketSet的值。但是你想要返回一个指向新票集的指针,而不是它的值。

TicketSet toAdd;

当此函数返回时,toAdd超出范围并被销毁。那不是你想要的。