函数接受结构指针和返回结构指针有奇怪的行为?(代码片段)

author author     2023-05-12     134

关键词:

我的代码我调用了insert函数,它传递一个指向struct(table)的指针,insert函数接收一个指针并执行一些操作并再次返回它。但是运行代码会导致分段错误。当我尝试使用传递的指针访问struct数组中的值。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define __USE_BSD
#include <string.h>

#include "speller.h"
#include "dict.h"

typedef struct 
 // hash-table entry
  Key_Type element; // only data is the key itself
  enum empty, in_use, deleted state;
 cell;

typedef unsigned int Table_size; // type for size-of or index-into hash table

struct table 

  cell *cells; Table_size table_size; // cell cells [table_size];
  Table_size num_entries; // number of cells in_use
  // add anything else that you need
;

int hashfunc(Key_Type k, Table_size size)

    printf("enterd
");
    char * d = k;
    int hash = 0;
    int c;
    printf("%s
", d);
    printf("wtf??
");
    while (c = *d++)
    
        printf("maybehere??
");
        hash = hash + c;
    
    hash = hash%size;
    printf("%d
", hash);
    return hash;


Table initialize_table (Table_size size) 

    Table t = malloc(sizeof(struct table));
    t->table_size = size;
    cell hash_table[size];
    for (int i=0; i<size; i++)
    
        hash_table[i].state = empty;
        hash_table[i].element = "-";
        //printf("initialised
");
    
    t->num_entries = 0;
    t->cells = hash_table;
    /*for (int i = 0; i < t->table_size; i++)
    
        printf("%d %s
", i, (t->cells + i)->element);
    */
    return t;


int a = 0;
Table insert (Key_Type k, Table t) 

    //printf("insert called %d
", a);
    printf("%d
", t->table_size);
    //printf("%s
", (t->cells + 2)->element);
    // as soon as program reaches here i get output like - 1 (NULL) 
    2 (NULL) and then segmentation fault
    for (int i = 0; i < t->table_size; i++)
    
        printf("%d %s
", i, (t->cells + i)->element);
    
    a++;
    printf("%s
", k);
    int hash_code = hashfunc(k, t->table_size);
    // Linear Probing
    printf("im here
");
    while(strcmp((t->cells + hash_code)->element,"-") != 0)
    
        if (strcmp((t->cells + hash_code)->element,k) == 0)
        
            printf("return at if
");
            return t;
        
        else if (hash_code == (t->table_size - 1))
            hash_code = 0;
        else
            hash_code++;
    
    (t->cells + hash_code)->element = k;
    (t->cells + hash_code)->state = in_use;
    t->num_entries += 1;
    printf("return at end with value %s
", k);
    printf("inserted value %s
", (t->cells + hash_code)->element);
    return t;



Boolean find (Key_Type k, Table t) 

    return FALSE;


void print_table (Table t) 

    Table_size size = t->table_size;
    for (int i = 0; i<size; i++)
    
        if (strcmp((t->cells + i)->element,"-") != 0)
            printf("%d %s
", i, (t->cells + i)->element);
    


void print_stats (Table t) 



void main()


    Table table;
    Table_size table_size = 19;
    int a = 5;
    Key_Type input[5] = "a","b","ab","abc","abcd";
    table= initialize_table (table_size);
    //printf("%s
", input[1]);
    while (a)
    
        table= insert("a",table);
        a--;
    
    printf("printing table
");
    print_table(table);

这是dict.h代码

typedef char* Key_Type;
typedef struct table* Table;    // allows different definitions of struct table

Table initialize_table ();      // allows different parameters
Table insert (Key_Type, Table);
Boolean find (Key_Type, Table);
void print_table (Table);
void print_stats (Table);

这是speller.h代码

typedef enum FALSE, TRUE Boolean;

extern int verbose; // used to control monitoring output
extern int mode;    // used to control your algorithm

extern char *prog_name; // used by check

void check (void *memory) ; // check result from strdup, malloc etc.

我相信我不明白指针在这个程序中是如何工作的。

答案

这是问题所在,

cell hash_table[size];

然后,你使t->cells指向hash_table,但hash_tableinitialize_table()函数中的局部变量,因此当函数返回时它被销毁/解除分配,并且在它返回后不再可访问。

你也应该在堆上分配它,就像这样

cell *hash_table;
hash_table = malloc(size * sizeof(*hash_table));
if (hash_table == NULL)
    return NULL; // Probably free `t' so that no memory leaks
                 // happen

访问在函数的堆栈帧中分配的这样的局部变量,在该函数返回之后是未定义的行为,问题可能发生在代码中的其他地方或者当访问指向解除分配的数据的指针时。

旁注

与命名一致,并且毫不含糊,你使用了一个奇怪的CamelCase和下划线组合,无论它是否奇怪都没关系,保留它并在整个代码中保留它 - 尊重你自己的风格。并称之为cell typedefCell

另外,总是检查malloc()的返回值,它返回错误(分配失败)时返回NULL,你应该编写代码,好像所有坏事都会发生,因为它们会发生。

最后,从来没有typedef指针。它没有任何帮助,它只是模糊了一个声明是指针的事实。

奇怪的指针行为 C++ / 继承

...这个派生类继承了一些成员变量和这些变量的一些get/set函数。这个派生类还实现了两个从基类继承的纯虚函数。现在在包含与这些类交互的代码的主文件中,我有三个 查看详情

go语言基础函数,数组,指针,结构体(代码片段)

目录函数匿名函数函数闭包的简单使用以及获取键盘输入闭包加上函数多返回值为什么闭包不会被垃圾回收defer内置函数panic、recover语言变量作用域数组数组定义数组+函数+宏定义二维数组指针make和new的区别二级指针的使... 查看详情

go语言基础函数,数组,指针,结构体(代码片段)

目录函数匿名函数函数闭包的简单使用以及获取键盘输入闭包加上函数多返回值为什么闭包不会被垃圾回收defer内置函数panic、recover语言变量作用域数组数组定义数组+函数+宏定义二维数组指针make和new的区别二级指针的使... 查看详情

go结构体方法

...uncmain() /* 方法:method 一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。 所有给定类型的方法属于该类型的方法集 语法: func(接受者)方法名(参数列表)(返回值列表) ... 查看详情

结构体作为函数参数值传递的问题

...地址与传结构体指针二者都可以作为传出参数,因为接受函数必须为其定义一个结构指针来接收,这样在函数内就可以修改结构体,在这点上二者没有区别。定义结构体指针未分配地址空间就作为参数传递会,如果你想把它作为... 查看详情

调用一个动态库中的函数,这个函数有一个参数是结构体指针,我如何使用这个指针?

...库中的结构体指针,它就好比是一个返回值。在我自己的函数里定义了一个结构体指针,将其传递给这个动态库中的函数,将动态库函数中的结构体指针赋给我定义的结构体指针,但其值并不是动态库函数中结构体指针的值,怎... 查看详情

golang指针和结构体

...p。这样,指针变量p也就指向了变量a所在的内容空间。new函数返回一个指针变量fmt.scan()就是传入一个指针变量。两种方法都可以使用。以上简要介绍了go语言中的指针和结构体。 查看详情

返回类中的结构指针

...1-09-2406:56:11【问题描述】:所以我写了一个类,其中一个函数返回一个结构,函数和结构都包含在类的私有部分中。是这样的:template<typenameT>classmyClassprivate:structmyStruct...Titem;...;myStruct*func(myStruct* 查看详情

函数指针和指针函数的区别(代码片段)

指针函数:指带指针函数,即本质是一个函数,函数返回类型为某种类型的指针类型标识符函数名(参数列表)intf(x,y);首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也... 查看详情

go结构,结构嵌套,接口,指针的测试和结论

...与子结构无关系了;//3.赋值给接口对象I1,或者接口作为函数参数时,I1:=& 查看详情

返回指向结构数组的指针(代码片段)

...t;length;++i)arr[i].x=n++;arr[i].y=m++;return&arr;当我编译包含此函数的程序时,它警告我我正在返回局部变量的地址。我假设这是因为指针在函数内(即在堆栈上)初始化,因此它被计为局部变量。当我编译它,忽略这个警告,并且无... 查看详情

在结构中分配内存时出现不可预测的行为

...本4.9.2(tdm-1),不确定它是错误还是我遗漏了什么?向/从函数发送结构 查看详情

C ++使用成员函数返回结构指针属性的值

】C++使用成员函数返回结构指针属性的值【英文标题】:C++Usememberfunctiontoreturnvalueofastruct\'spointerproperty【发布时间】:2017-04-2420:00:18【问题描述】:我正在使用SDL学习一些C++,但遇到了一个令人困惑的问题。我在头文件中有一个... 查看详情

go笔记:方法(代码片段)

...现这些特性。1、方法的声明  Go中的方法是一种特殊的函数,与struct相关联,被称为struct的接收者。可以理解为方法就是有接收者的函数。语法格式如下:typemystructstructfunc(recvmystruct)my_method(para)return_typefunc(recv*mystruct)my_method(pa... 查看详情

使用 C 语言的字符串中的奇怪字符(结构、指针和字符串)

】使用C语言的字符串中的奇怪字符(结构、指针和字符串)【英文标题】:WeirdcharactersinstringwithC(Structs,pointers,andstrings)【发布时间】:2021-07-0104:31:05【问题描述】:您好,我正在创建一个包含学生信息的链接列表。但是,当显... 查看详情

使用指向结构数组的指针不会返回完整的数组

...010:45:11【问题描述】:我有一个主程序,它应该通过调用函数来加载数据(结构数组,未定义大小)、正确的数据,然后继续处理它。以下是我正在尝试做的一个小例子。函数loadData接收指向主指针的指针,从而可以通过malloc为... 查看详情

混合 C/C++ 代码中的结构指针

...布时间】:2014-12-1108:03:23【问题描述】:我在从C++调用C函数时遇到问题。特别是,我有一个具有C结构成员变量的类的实例。我将指向该变量的指针传递给一个C函数,该函数是从成员函数调用的。我观察到变量指针地址在C函数... 查看详情

在结构外调用函数指针

】在结构外调用函数指针【英文标题】:Callapointer-to-functionoutsidethestructure【发布时间】:2018-10-1412:36:23【问题描述】:我有一个结构,里面有一个指向同一结构的函数的指针。现在我需要调用一个指向结构外函数的指针。我举... 查看详情