首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在struct字段中指定用于其他函数的字符串的分段错误

在struct字段中指定用于其他函数的字符串的分段错误
EN

Stack Overflow用户
提问于 2014-08-07 14:27:36
回答 2查看 117关注 0票数 0

我声明了以下结构。在第二个函数中,我声明该类型的结构,然后尝试填充string字段。但是,如果我试图在其他函数中访问这个字段,它就给了我一个seg错误。所有声明是否正确,还是需要malloc?此外,此结构中的其他字段似乎已正确存储,但字符串名称除外。

代码语言:javascript
复制
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;

其中一个函数创建如下结构:

代码语言:javascript
复制
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将返回到这个函数中:

代码语言:javascript
复制
   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打印时,它给了我以下内容:

代码语言:javascript
复制
 00000029 and (Ps
 0000000d and �Oh
 00000014 and �Oh
 00000012 and main
 00000014 and P_
 00000015 and P)

乱七八糟的字符是字符串应该在的位置,其他的一切都很好。Lfind是标准的C lfind函数,我还没有定义它。

打印lfind返回的符号的大小是可以的,但不打印名称,这是一个seg错误。为什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-07 15:15:31

正如Michael在评论中所说:在堆栈上分配数组。返回后,它将超出作用域,与其关联的内存将被覆盖。你需要改变这一点:

代码语言:javascript
复制
PrintedSymbol arr[size];

至:

代码语言:javascript
复制
PrintedSymbol* arr = malloc(sizeof(PrintedSymbol) * size);

除此之外,您没有在这里进行任何边界检查:

代码语言:javascript
复制
char *str_location = (char *) string_data + symbol.name;

如果symbol.name把你放在string_data之外,就会出问题。

编辑:你对你的类型犯了错误。Symbol有一个名为name的成员,但它是一个int,而不是char*。因此,当您尝试打印它时,它会将它找到的字节解释为char*,并给出垃圾。

你可能是说:

代码语言:javascript
复制
PrintedSymbol matched = *(PrintedSymbol*) matching; 

编辑:lfind具有以下签名:

代码语言:javascript
复制
 void*  lfind ( const void * key, const void * base, size_t num, size_t width, int (*fncomparison)(const void *, const void * ) ); 

当你打电话:

代码语言:javascript
复制
 lfind(&key, arr, &symbol_size, count, compare_address);

并将&symbol_size作为参数传递给num,得到一个非常大的值。看起来,您还颠倒了numwidth。这可能会导致意想不到的行为。你可能是说:

代码语言:javascript
复制
 lfind(&key, arr, count, symbol_size, compare_address);

您应该打开-Wall,因为gcc会警告您,如果您试图传递一个size_t*,其中函数需要一个size_t

票数 2
EN

Stack Overflow用户

发布于 2014-08-07 15:35:36

函数中局部变量的地址取决于调用函数时执行点的堆栈状态( SP寄存器的值)。

换句话说,每次调用函数时,这个地址都不是相同的。

因此,返回局部变量的地址会导致未定义的行为。

使用return arr,本质上是在内存中返回arr的地址。

请注意,对于数组(与其他类型的变量不同),不存在"value“这样的东西。

例如:

代码语言:javascript
复制
int  var;    // mostly var != &var
int* ptr;    // mostly ptr != &ptr
int  arr[4]; // always arr == &arr

因此,虽然在正确初始化varptr之后可以安全地返回它们,但是您可能不会使用arr来返回它们。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25185108

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档