2015-04-15 5 views
1

У меня есть огромная проблема, которую я пробовал решать разными способами, но не смог найти решение.Работа с указателями и структурами

Что я должен сделать, это:

  1. создать функцию для введения 2 устанавливает
  2. другой функции для отображения этих наборов

Необходимо использовать структуру, компоненты которого будут :

  1. количество элементов для соответствующего набора;
  2. указатель (для хранения элементов этих двух комплектов);

    Я не знаю почему, но когда я выполняю программу (представленную ниже), второй элемент первого набора не отображается. Пожалуйста, если у вас есть время, вы можете помочь мне найти проблему. Это действительно расстраивает, когда все кажется прекрасным, и все же программа не работает. Большое спасибо !!!

В заголовке у меня есть:

#ifndef L8_3H_H_ 
#define L8_3H_H_ 

struct Set 
{ 
    unsigned int card; 
    double *p[2]; 
}; 

typedef struct Set MULTIME; 

MULTIME *introduce_data(); 
void showSet(MULTIME *m, int j); 

#endif /* L8_3H_H_ */ 

В главный у меня есть:

#include "L8_3h.h" 
    #include <stdio.h> 

int main(void) 
{ 
    MULTIME *mult; 


    mult = introduce_data(); 

    showSet(mult, 0); 
    showSet(mult, 1); 

return 0; 
} 

Мои функции являются:

#include "L8_3h.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

void showSet(MULTIME *m, int j) 
{ 
    int i; 



    if (j == 0) 
    { 
     printf("\nA = {"); 
    }else 
    { 
     printf("\nB = {"); 
    } 

    for (i = 0; i < (m + j)->card; ++i) 
    { 
     printf("%lf", *((m + j)->p[j]+i)); 

     if (i != (m + j)->card - 1) 
     { 
      printf(", "); 
     } 
    } 

    printf("}"); 
} 


MULTIME *introduce_data() 
{ 
    MULTIME *mult = (MULTIME*)malloc(sizeof(MULTIME)); 
    int i, j; 


    for (i = 0; i < 2; ++i) 
    { 


     printf("\nIntroduce the number of elements of set %d", i + 1); 
     scanf("%u", &(mult + i)->card); 


     (mult+i)->p[i] = (double*)malloc(sizeof(double)*((mult+i)->card)); 


     printf("\nIntroduce the element of set %d\n", i+1); 
     for (j = 0; j < (mult + i)->card; ++j) 
     { 
      scanf("%lf", ((mult + i)->p[i]+j)); 
//It's interesting that when I put a printf right after introducing the 
//element everything is fine(I get the right element) 
     } 


    } 


    printf("\nHeres the problem"); 
    printf("\nThis should not be zero: %lf", *((mult + 0)->p[0]+1)); 

return mult; 
} 

ответ

1

Существует ряд проблем в пределах introduce_data(). Я могу быстро просмотреть.

Во-первых, преобразование возвращаемое значение malloc(), как и в

MULTIME *mult = (MULTIME*)malloc(sizeof(MULTIME)); 

не является необходимым. Удалите преобразование (MULTIME *) и убедитесь, что в верхней части вашего кода есть #include <stdlib.h>. Оставляя #include <stdlib.h> и используя преобразование, ваш код имеет неопределенное поведение. (Единственным исключением является то, что ваш компилятор C на самом деле является компилятором C++ - в этом случае вам необходимо ОБА #include <stdlib.h> и преобразование. В противном случае не используйте преобразование.).

Во-вторых, malloc() в распределяет память для mult как единый MULTIME. Затем цикл использует mult, как если бы он был массивом из двух MULTIME. Это падает с конца (динамически выделенного массива). Поведение не определено.

В-третьих, вы получаете неправильное сопоставление синтаксиса массива и синтаксиса указателя. Заявление

(mult+i)->p[i] = (double*)malloc(sizeof(double)*((mult+i)->card)); 

функционально эквивалентен (с сбросив преобразование типа), чтобы

mult[i].p[i] = malloc(sizeof(double)*(mult[i].card)); 

Аналогично, оператор

scanf("%lf", ((mult + i)->p[i]+j)); 

эквивалентно

scanf("%lf", mult[i].p[i]+j); 

Оба это, вероятно, нет что вы намерены.

Основная проблема заключается в том, что вы неправильно понимаете, как указатели работают с массивами. Вам нужно будет более внимательно прочитать учебник.

+0

Большое спасибо. Ваш ответ был очень полезен. Проблема с моей программой была действительно тем, что вы заметили: я работал с «mult» (который был объявлен как один тип элемента MULTIME), как будто с массивом из двух элементов. В тот момент, когда я изменил MULTIME * mult = (MULTIME *) malloc (sizeof (MULTIME)) "MULTIME * mult = (MULTIME *) malloc (sizeof (MULTIME) * 2) все прошло хорошо. Спасибо. –

1

это кажется неправильным

struct Set 
{ 
    unsigned int card; 
    double *p[2]; 
}; 

у вас есть набор с 2 списками номера. Я думаю, что каждый комплект должен иметь один список

struct Set 
{ 
    unsigned int card; 
    double *p; 
}; 

вещи от этого плохого. Вам нужно создать 2 экземпляра Set и загрузить данные в каждый. Я бы создал функцию Load_Set, которая принимает двойной список и возвращает новый malloced Set

+0

Вы имеете в виду под «двумя экземплярами Set», что я должен создать массив типа Set? –

+0

Я добавил комментарий в свою программу. Он находится во второй функции и начинается с: «Интересно, когда ...». Разве вы не знаете, что может быть проблемой для этого? Спасибо. –

0

Надеюсь, это будет полезно для других, столкнувшихся с одной и той же проблемой.

Наконец, благодаря Петру, я понял, в чем проблема. Питер заметил, что я использовал переменную mult как массив из двух элементов типа MULTIME, тогда как он был объявлен как одноэлементная переменная.

Итак, после того, как это изменить:

MULTIME *mult = (MULTIME*)malloc(sizeof(MULTIME)); 

к этому:

MULTIME *mult = (MULTIME*)malloc(sizeof(MULTIME)*2); 

Я, наконец, получил правильный результат.