我非常关注以下问题。非常感谢任何帮助!
基本上我有一个包含结构数组的程序,当我调用外部函数时,我遇到了分段错误。只有当我传递的数组超过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
}
答案 0 :(得分:2)
你可能会炸掉筹码。将数组移动到函数外部,即从auto
移动到static
。
另一个选择是// ... more code - array gets populated...
部分正在破坏堆栈。
发布更多代码后 - 您在堆栈上使用C99可变大小的数组 - Bad IdeaTM
。想想当您的数据集增长到数千或数百万条记录时会发生什么。切换到动态内存分配,请参阅malloc(3)
。
答案 1 :(得分:1)
你没有告诉我们listsize
是什么,但我认为它是一个变量,而不是一个常量。
您使用的是可变长度数组,VLA。如果它们太大而有些危险,因为它们通常分配在堆栈上。
要解决这个问题,你可以动态分配这样的野兽
struct ratingObj (*movies)[listSize] = malloc(sizeof(*movies));
// ...
free(movies);
然后你会想到movies
然后是一个指向数组的指针,所以你必须比以前更多地引用一个*
。
另一个更经典的C版本将是
struct ratingObj * movies = malloc(sizeof(*movies)*listsize);
// ...
free(movies);