Внешние функции и ограничение размера параметра (C) - PullRequest
0 голосов
/ 02 марта 2011

Я очень застрял в следующем выпуске.Любая помощь очень ценится!

В основном у меня есть программа, которая содержит массив структур, и я получаю ошибку сегментации при вызове внешней функции.Ошибка возникает только тогда, когда в массиве передается более 170 элементов.

Ничего в функции не обрабатывается.Программа останавливается точно при доступе к функции.

Существует ли ограничение на размер параметров, передаваемых внешним функциям?

Main.c

struct ratingObj {
    int uid;
    int mid;
    double rating;
};

void  *FunctionLib;     /*  Handle to shared lib file   */
void (*Function)();     /*  Pointer to loaded routine   */
const char *dlError;        /*  Pointer to error string */

int main( int argc, char * argv[]){
// ... some code ...
    asprintf(&query, "select mid, rating "
                     "from %s "
                     "where uid=%d "
                     "order by rand()", itable, uid);
    if (mysql_query(conn2, query)) {
        fprintf(stderr, "%s\n", mysql_error(conn2));
        exit(1);
    }
    res2 = mysql_store_result(conn2);
    int movieCount = mysql_num_rows(res2);
    // withhold is a variable that defines a percentage of the entries 
    // to be used for calculations (generally 20%)
    int listSize = round((movieCount * ((double)withhold/100)));
    struct ratingObj moviesToRate[listSize];
    int mvCount = 0;
    int count =0;
    while ((row2 = mysql_fetch_row(res2)) != NULL){
        if(count<(movieCount-listSize)){
            // adds to another table
        }else{
            moviesToRate[mvCount].uid = uid;
            moviesToRate[mvCount].mid = atoi(row2[0]);
            moviesToRate[mvCount].rating = 0.0;

            mvCount++;
        }
        count++;
    }
    // ... more code ...
    FunctionLib = dlopen("library.so", RTLD_LAZY);
    dlError = dlerror();
    if( dlError ) exit(1);
    Function = dlsym( FunctionLib, "getResults");
    dlError = dlerror();
    (*Function)( moviesToRate, listSize );
// .. more code
}

library.c

struct ratingObj {
    int uid;
    int mid;
    double rating;
};

typedef struct ratingObj ratingObj;

void getResults(struct ratingObj *moviesToRate, int listSize);

void getResults(struct ratingObj *moviesToRate, int listSize){
// ... more code
}

Ответы [ 2 ]

2 голосов
/ 02 марта 2011

Вероятно, вы взорвали стек.Переместите массив за пределы функции, то есть от auto до static land.

Другой вариант заключается в том, что часть // ... more code - array gets populated... портит стек.

Edit 0:

После того, как вы разместили больше кода - вы используете C99 массив переменных размера в стеке - Bad Idea<sup>TM</sup>.Подумайте, что произойдет, когда ваш набор данных вырастет до тысяч или миллионов записей.Переключитесь на динамическое распределение памяти, см. malloc(3).

1 голос
/ 03 марта 2011

Вы не показываете, что такое listsize, но я полагаю, что это переменная, а не константа.

То, что вы используете, это массивы переменной длины, VLA.Это немного опасно, если они слишком велики, так как они обычно располагаются в стеке.

Чтобы обойти это, вы можете выделить такого зверя динамически

struct ratingObj (*movies)[listSize] = malloc(sizeof(*movies));
// ...
free(movies);

Затем вы получитеИмейте в виду, что movies является указателем на массив, поэтому вам нужно ссылаться на один * больше, чем прежде.

Другая, более классическая версия C будет

struct ratingObj * movies = malloc(sizeof(*movies)*listsize);
// ...
free(movies);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...