我声明了以下结构。在第二个函数中,我声明该类型的结构,然后尝试填充string字段。但是,如果我试图在其他函数中访问这个字段,它就给了我一个seg错误。所有声明是否正确,还是需要malloc?此外,此结构中的其他字段似乎已正确存储,但字符串名称除外。
typedef struct {
unsigned int name; // offset into string table for symbol name
uintptr_t addr; // symbol address
unsigned int size; // symbol size in bytes
} Symbol;
typedef struct {
char *name;
unsigned int address;
int size;
char binding;
} PrintedSymbol;其中一个函数创建如下结构:
PrintedSymbol* create_symbols(char *string_data, Symbol *symbols) {
Symbol symbol;
int count = 0;
int size = 22;
PrintedSymbol *arr = malloc(sizeof(PrintedSymbol) * size);
for (int i = 0; i < size; i++) {
PrintedSymbol unique;
symbol = symbols[i];
char *str_location = (char *) string_data + symbol.name;
char *str_name = strdup(str_location);
unique.name = str_name;
arr[count] = unique;
count++;
}
Array printthis;
printthis.arr = arr;
printthis.count = count;
return printthis;
}编辑:我还编辑了上面的功能-注,我仍然没有错误的,因为我是存储在一个结构。
我正试图通过以下操作打印姓名:
我已经将数组和它的计数一起存储在另一个结构中,如下所示:this struct { PrintedSymbol *arr;int } array
现在,函数PrintedSymbol将返回到这个函数中:
void output_symbols(Array printthis, char *hex, char *string_data, Symbol *symbols) {
// set-up variables from struct
PrintedSymbol *arr = printthis.arr;
int count = printthis.count;
if (hex == NULL) {
print_symbol_table(arr, count); <-- THIS FUNCTION IS PRINTING OUT THE ARRAY PROPERLY
} else {
PrintedSymbol key;
qsort(arr, count, sizeof(key), lex_sort);
key.address = strtol(hex, NULL, 16);
key.size = 1;
size_t symbol_size = sizeof(key);
void *matching = lfind(&key, arr, &symbol_size, count, compare_address);
unsigned int hex_int = strtol(hex, NULL, 16);
if (matching != NULL) {
PrintedSymbol matched = *(PrintedSymbol *) matching;
printf("%d and %s\n", hex_int, matched.name, matched.size); <-- printing the SIZE is fine, the NAME gives a segfault!
}
}当我用malloc打印时,它给了我以下内容:
00000029 and (Ps
0000000d and �Oh
00000014 and �Oh
00000012 and main
00000014 and P_
00000015 and P)乱七八糟的字符是字符串应该在的位置,其他的一切都很好。Lfind是标准的C lfind函数,我还没有定义它。
打印lfind返回的符号的大小是可以的,但不打印名称,这是一个seg错误。为什么?
发布于 2014-08-07 15:15:31
正如Michael在评论中所说:在堆栈上分配数组。返回后,它将超出作用域,与其关联的内存将被覆盖。你需要改变这一点:
PrintedSymbol arr[size];至:
PrintedSymbol* arr = malloc(sizeof(PrintedSymbol) * size);除此之外,您没有在这里进行任何边界检查:
char *str_location = (char *) string_data + symbol.name;如果symbol.name把你放在string_data之外,就会出问题。
编辑:你对你的类型犯了错误。Symbol有一个名为name的成员,但它是一个int,而不是char*。因此,当您尝试打印它时,它会将它找到的字节解释为char*,并给出垃圾。
你可能是说:
PrintedSymbol matched = *(PrintedSymbol*) matching; 编辑:lfind具有以下签名:
void* lfind ( const void * key, const void * base, size_t num, size_t width, int (*fncomparison)(const void *, const void * ) ); 当你打电话:
lfind(&key, arr, &symbol_size, count, compare_address);并将&symbol_size作为参数传递给num,得到一个非常大的值。看起来,您还颠倒了num和width。这可能会导致意想不到的行为。你可能是说:
lfind(&key, arr, count, symbol_size, compare_address);您应该打开-Wall,因为gcc会警告您,如果您试图传递一个size_t*,其中函数需要一个size_t。
发布于 2014-08-07 15:35:36
函数中局部变量的地址取决于调用函数时执行点的堆栈状态( SP寄存器的值)。
换句话说,每次调用函数时,这个地址都不是相同的。
因此,返回局部变量的地址会导致未定义的行为。
使用return arr,本质上是在内存中返回arr的地址。
请注意,对于数组(与其他类型的变量不同),不存在"value“这样的东西。
例如:
int var; // mostly var != &var
int* ptr; // mostly ptr != &ptr
int arr[4]; // always arr == &arr因此,虽然在正确初始化var或ptr之后可以安全地返回它们,但是您可能不会使用arr来返回它们。
https://stackoverflow.com/questions/25185108
复制相似问题