2014-08-29 6 views
0

У меня возникли проблемы с пониманием того, почему этот фрагмент кода работает неправильно.Проблемы с указателем и строкой

#include <stdio.h> 
#include <stdlib.h> 
#include "runSolver.h" 

typedef struct testStruct { 
    double *x[11]; 
    double *u[10]; 
} Test; 

typedef struct returnStruct_t { 
    Test* vars; 
} ReturnStruct; 

void initalize_returnStruct(void** returnStruct){ 
    ReturnStruct* new_returnStruct = (ReturnStruct *)malloc(sizeof(new_ReturnStruct)); 
    Test* varsStruct = (Test*)malloc(sizeof(Test)*3); 

    int dataSize = 5; 
    int i; 
    for(i = 0; i < 3; i++){ 
    int x; 
    for(x = 0; x < 11; x++){ 
     fprintf(stderr, "i:%d and x:%d for x\n", i, x); 
     varsStruct[i].x[x] = (double *)malloc(sizeof(double)*5);  
    } 
    for(x = 0; x < 10; x++){ 
     fprintf(stderr, "i:%d and x:%d for u\n", i, x);  
     varsStruct[i].u[x] = (double *)malloc(sizeof(double)*5);  
    } 
    } 

    new_returnStruct->vars = varsStruct; 
    *returnStruct = new_returnStruct; 
} 

Эта функция вызывается с помощью языка Python ctypes:

#!/usr/bin/python 

import ctypes as ct 

class returnStruct_t(ct.Structure): 
    _fields_ = [("vars", Test_t*3)] 

runSolver = ct.CDLL('./runSolverParallel.so') 

varsd = ct.c_void_p() 
runSolver.initalize_returnStruct(ct.byref(varsd)) 

То, что я пытаюсь сделать, это следующее:

  • проход в пустой указатель на указатель с именем returnPointer

  • Создайте экземпляр указателя для ввода ReturnStruct

  • экземпляр указатель на массив размером 3 типа Test

  • Instantiate Test элементы данных структуры в x и u

  • имеют returnPointer точку в полностью инстанцирован ReturnStruct

Когда я запускаю код, как указано в нем, gfaults на первой итерации второго внутреннего цикла while, когда я пытаюсь выделить место для new_returnStruct->vars[0].u[0]. Если я полностью исключаю отклонение от double *u[10] и его установку, я получаю segfault на линии, где я установил returnPointer, чтобы указать на ReturnStruct: *returnStruct = new_return;. Честно говоря, я не в курсе, что, черт возьми, происходит. Любая помощь будет большой.

PS: Я использую double *x[11]; double *u[10];, а не double **x; double **u;, потому что структура Test не является реальной структурой, которую я буду использовать. Реальная структура определяется в другом месте библиотеки и имеет эти две переменные, а также около 20 некоторых других переменных double *. Я хочу в конечном итоге заменить Test на эту структуру, но я хочу, чтобы этот код работал с Test. Просто для справки реальной структуры Test будет заменена является:

typedef struct Vars_t { 
    double *u_0; /* 1 rows. */ 
    double *u_1; /* 1 rows. */ 
    double *u_2; /* 1 rows. */ 
    double *u_3; /* 1 rows. */ 
    double *u_4; /* 1 rows. */ 
    double *u_5; /* 1 rows. */ 
    double *u_6; /* 1 rows. */ 
    double *u_7; /* 1 rows. */ 
    double *u_8; /* 1 rows. */ 
    double *u_9; /* 1 rows. */ 
    double *x_1; /* 5 rows. */ 
    double *x_2; /* 5 rows. */ 
    double *x_3; /* 5 rows. */ 
    double *x_4; /* 5 rows. */ 
    double *x_5; /* 5 rows. */ 
    double *x_6; /* 5 rows. */ 
    double *x_7; /* 5 rows. */ 
    double *x_8; /* 5 rows. */ 
    double *x_9; /* 5 rows. */ 
    double *t_01; /* 1 rows. */ 
    double *t_02; /* 1 rows. */ 
    double *t_03; /* 1 rows. */ 
    double *t_04; /* 1 rows. */ 
    double *t_05; /* 1 rows. */ 
    double *t_06; /* 1 rows. */ 
    double *t_07; /* 1 rows. */ 
    double *t_08; /* 1 rows. */ 
    double *t_09; /* 1 rows. */ 
    double *t_10; /* 1 rows. */ 
    double *x_10; /* 5 rows. */ 
    double *u[10]; 
    double *x[11]; 
} Vars; 
+2

я не знаю, как это даже * компилирует *. 'return', имя параметра для вашей первой перечисленной функции является зарезервированным словом. Поместите код * real * в комплекте с 'int main()', который сгенерировал вывод, который вы представляете, вместе с списком '# include' в верхней части файла и любыми/всеми шагами, которые вы сделали для * debug * этот. Обратный след из 'gdb', скорее всего, будет говорить на томах. – WhozCraig

+0

@WhozCraig Opps не уверен, как это изменилось до 'return', это должно быть' returnStruct'. Также я вызываю эту функцию из python через 'ctypes', поэтому нет' int main() '. Однако я опубликую код python. – ryan

+0

Ну, это segfaults, потому что вы не выделяете память для 'new_returnStruct-> vars' перед разыменованием этого указателя. Кроме того, вы должны использовать malloc (sizeof (* new_returnStruct)) вместо текущего кода в первой строке, хотя это, скорее всего, не является причиной сбоя. – kfx

ответ

1

В своем коде вы выделения памяти для ReturnStruct * указатель не фактическая структура Вместо

ReturnStruct* new_returnStruct = (ReturnStruct *)malloc(sizeof(new_returnStruct)); 

попробовать этот

ReturnStruct* new_returnStruct = (ReturnStruct *)malloc(sizeof(ReturnStruct)); 
+1

Кроме того, ** не требуется ** для перевода 'malloc'. Просто используйте: 'ReturnStruct * new_returnStruct = malloc (sizeof (ReturnStruct));' –

2

Есть некоторые ошибки в коде:

Эта линия hould быть ReturnStruct и не new_returnStruct, как параметр sizeof:

ReturnStruct* new_returnStruct = (ReturnStruct *)malloc(sizeof(new_returnStruct)); 

Вы уверены, что sizeof(Test) == sizeof(Pee)*3 или на самом деле, почему вы используете Pee вместо Test?

Test* varsStruct = (Test*)malloc(sizeof(Pee)*3); 
+1

Я не вижу проблемы с 'varsStruct [i] .x [0]' (это было бы неверно, если 'varsStruct' был' Test ** '). 'sizeof varsStruct-> x' в порядке,' sizeof (double) * 11' определенно неверен ('sizeof (double *) * 11' также будет правильным). – mafso

+0

Я переименовал 'Pee' в' Test' для этой публикации. Просто забыл изменить его в этом одном месте. Спасибо за помощь, хотя! – ryan

+0

Прочтите def 'varsStruct': это' Test * '. С 'i = 1', это segfault или ничего, кроме того, что он должен (однако, даже если я не делаю C сейчас, я уверен, что я не ошибаюсь в этом). – NoDataFound