0

converting some python code to C. 'just' want to declare a typedef structure and a pointer to it... this is segfaulting at printf( "byte order %p\n", info->byte_order); How is this supposed to be done? please help. Trying to follow C typedef of pointer to structure but I guess it is outdated.

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <Byteswap.h>

#define WFM_HEADER_SIZE 838

typedef struct WfmInfo{
  uint16_t byte_order;
//  char version[8];
  uint32_t imp_dim_count;
  uint32_t exp_dim_count;
  uint32_t record_type;
  uint32_t exp_dim_1_type;
  uint32_t time_base_1;
  uint32_t fastframe;
  uint32_t Frames;
  double   tstart;
  double   tscale;
  double   tfrac;
  double   tdatefrac;
  int32_t  tdate;
  uint32_t dformat;
  double   vscale;
  double   voffset;
  uint32_t pre_values;
  uint32_t post_values;
  uint32_t avilable_values;
  uint32_t dpre;
  uint32_t dpost;
  uint16_t bps;
  uint32_t code;
  uint32_t readbytes;
  uint32_t allbytes ;
  uint32_t samples;
  uint64_t curve_offset;
  uint32_t available_values;
} WfmInfo;

typedef WfmInfo* WfmInfo_ptr;

int testFuck(){
    WfmInfo_ptr info;
    printf( "info address %p\n", info);
    printf( "byte order %p\n", info->byte_order);
    cout<<"info declared"<<endl;
    return 0;
}
PatEugene
  • 176
  • 1
  • 10

2 Answers2

1

Here is a minimal example.

want to declare a typedef structure and a pointer to it...

Compile like this:

gcc main.c -o main
./main

See output like this:

info address 0x7ff7be2e19b8
byte order 0x7ff7be2e19b8 = 3
// main.c
#include <stdio.h>
#include <inttypes.h>

typedef struct WfmInfo{
  uint16_t byte_order;
} WfmInfo;

typedef WfmInfo* WfmInfo_ptr;

int main(){
    // allocate the structure on the stack
    WfmInfo info = { 3 };
    // assign pointer the address on the stack
    WfmInfo_ptr info_ptr = &info;

    // display address using structure address
    printf( "info address %p\n", &info);

    // display address using pointer and display value using pointer to access elements of structure
    printf( "byte order %p = %d\n", info_ptr, info_ptr->byte_order);
    return 0;
}
atl
  • 575
  • 3
  • 6
0

Your typedefs are correct, WfmInfo_ptr is the type of a pointer to a WfmInfo structure.

The problem in the main function is you define such a pointer info but do not initialize it, so both printf calls have undefined behavior:

  • printf( "info address %p\n", info); has undefined behavior because you %p expects a void * and you provide a WfmInfo *, which is not implicitly converted when passed to a vararg function
  • info is uninitialized, so even if it was passed as (void *)info, the output would be meaningless.
  • printf( "byte order %p\n", info->byte_order) has undefined behavior because you dereference an uninitialized pointer info.
  • cout<<"info declared"<<endl; is C++ code, not C.

Note also that hiding pointers behind typedefs is considered confusing and error prone.

Defining info as WfmInfo *info; is quite readable and makes it obvious that info is a pointer that is not implicitly initialized (unlike a structure or class that might have a default constructor in C++).

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Thanks for the info, I obviously have no clue what I'm doing. Does this mean in C++ this (initializing the pointer) is taken care of automatically behind the scenes when I do WfmInfo *info ? It's confusing to me that defining and initializing are even separate actions. Is defining the action of assigning a variable a type, and then initialization an address? – PatEugene Feb 16 '23 at 04:46
  • Wait, can I just do this without pointers? That would probably be fine. – PatEugene Feb 16 '23 at 05:47
  • Defining an object effectively sets aside a piece of memory that can be used with the given name for the purpose specified by the type: for example, on a 64-bit CPU, `WfmInfo *info;` allocates 8 bytes for use as a pointer to a `WfmInfo` structure. If this definition occurs at the global scope, this pointer is implicitly initialized as a null pointer (it does not point to any object), whereas if it appears in the body of a function, it is uninitialized, its bytes have whatever values are present in the memory when the function executes. In both cases, dereferencing it has undefined behavior. – chqrlie Feb 16 '23 at 09:38
  • Defining a structure works the same way: `WfmInfo info;` sets aside 144 bytes of memory for use as a structure, referred to as `info` in the scope of the definition. If you define a default constructor for `WfmInfo`, this function will be called to initialize the structure (in C++ only), otherwise all fields will be all zero of `info` is defined at the global scope and uninitialized if `info` is defined as a non-`static` local variable (the C behavior). – chqrlie Feb 16 '23 at 09:43
  • Here is a simple comparison: defining a global variable is like picking up a piece of paper from the pack, whereas defining a local variable is like picking one from the trashcan next to the copy machine... you may need to erase it before use and it will go back to the trashcan automatically when you leave the function. – chqrlie Feb 16 '23 at 09:46
  • I guess one thing I struggle with is why you have to define a default constructor. When wouldn't you want one? I suppose you could add some additional functionality to the constructor, so maybe the way to think of it is that you're allowed to define the constructor. – PatEugene Feb 28 '23 at 07:22
  • Also, paper analogy is helpful, I guess there may be cases when you don't want or don't have to bother 'erasing,' the paper. – PatEugene Feb 28 '23 at 07:24