I'm trying to make a game that requires dynamically sized arrays in C but my code isn't working even though identical code works in another one of my programs.
Here are my #includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SwinGame.h" //API for graphics, physics etc
#include <math.h>
Here are my typedefs for the relevant structs used:
typedef struct position_data
{
double x;
double y;
} position_data;
typedef enum enemy_type_data {CIRCLE, TRIANGLE, SQUARE} enemy_type_data;
typedef struct enemy_data
{
position_data location;
enemy_type_data type;
bitmap bmp;
double health;
double speed;
int path_to;
} enemy_data;
typedef struct enemy_data_array
{
int size;
enemy_data *data;
} enemy_data_array;
Here is the function to add an element to the array:
void add_enemy(enemy_data_array *enemies)
{
enemy_data *new_array;
enemies->size++;
new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size);
if (new_array) //if realloc fails (ie out of memory) it will return null
{
enemies->data = new_array;
// enemies->data[enemies->size - 1] = read_enemy_data();
printf("Enemy added successfully!\n");
}
else
{
printf("FAILED. Out of Memory!\n");
enemies->size--;
}
}
And here is my function call and variable declaration in the main procedure:
int main()
{
path_data my_path[41];
enemy_data_array enemies;
enemies.size = 0;
add_enemy(&enemies);
}
Why isn't this working?
You invoked undefined behavior by passing indeterminate value enemies->data in uninitialized variable having automatic storage duration. Initialize it before using add_enemy().
int main()
{
path_data my_path[41];
enemy_data_array enemies;
enemies.size = 0;
enemies.data = 0; /* add this line */
add_enemy(&enemies);
}
0 is a null pointer constant and can safely be converted to pointer NULL. Unlike NULL, 0 will work without including any headers. Of course you can use enemies.data = NULL; with proper header included.
#2501's explanation is completely correct. Another solution is to change your implementation of add_enemy() to something like this:
void add_enemy(enemy_data_array *enemies)
{
enemy_data *new_array;
// check if size was non-zero
if (enemies->size++)
{
new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size);
}
// start new allocation
else
{
new_array = (enemy_data *)alloc(sizeof(enemy_data) * enemies->size);
}
if (new_array) //if (re)alloc fails (ie out of memory) it will return null
{
enemies->data = new_array;
// enemies->data[enemies->size - 1] = read_enemy_data();
printf("Enemy added successfully!\n");
}
else
{
printf("FAILED. Out of Memory!\n");
enemies->size--;
}
}
If fails because you haven't cleared the content of "enemies". Since it is a stack variable, it will contain whatever garbage data is on the stack.
set enemies.data to NULL in the main function and try it again.
Related
I want to pass a 2D array to a function, and the value of the array will not be modified in that function. So I am thinking about doing this way:
#include <Windows.h>
static INT8 TwoDimArrayConst(const INT8 ai_Array[2][2]);
int main(void)
{
INT8 ai_Array[2][2] = { { { 1 }, { 2 } }, { { 3 }, { 4 } } };
(void)TwoDimArrayConst(ai_Array); // Message 0432: [C] Function argument is not of compatible pointer type.
return 1;
}
static INT8 TwoDimArrayConst(const INT8 ai_Array[2][2])
{
INT8 test = 0;
for (INT8 i = 0; i < 2; i++)
{
for (INT8 k = 0; k < 2; k++)
{
if (ai_Array[i][k] > 0)
{
test = 1;
}
}
}
if (test == 0)
{
test = 2;
}
return test;
}
However, it gave me the QAC error when I enabled depth 5 QAC setting as the one I put is the code comment above:
// Message 0432: [C] Function argument is not of compatible pointer type.
If I remove the const in the function declaration and definition, so the function is like:
static INT8 TwoDimArrayConst(INT8 ai_Array[2][2]);
this error will be gone, but there will be another error saying:
> The object addressed by the pointer parameter 'ai_Array' is not
> modified and so the pointer could be of type 'pointer to const'.
So how to resolve this dilemma? I cannot define ai_Array to be const array in the main fuction since some other function may still want to modify the value.
Also, I am looking for the solution that still maintain the double brackets(no need to pass row size and column size as separate arguments) in the function, instead of treat it as a 1D array.
the following proposed code:
uses the C library functions rather than the windows functions, since I'm running on linux, not windows
performs the desired functionality
cleanly compiles
takes advantage of arrays, in C, being laid out consecutively in memory
takes advantage of "accessing an array name degrades to the address of the first byte of the array"
removes all the unneeded braces (which are doing nothing but cluttering the code)
documents why each header file is included
passes the size of the array as an parameter to the called function (should always either do this or include some kind of 'marker' in the contents of the array)
all the above allows treating the array as a 1 dimensional array
breaks out of the loop in the called function as soon as the terminating condition is encountered
BTW: the header file: windows.h is not portable
and now, the proposed code:
//#include <Windows.h>
#include <stdio.h> // printf()
#include <stdint.h> // int8_t
static int8_t TwoDimArrayConst( const int8_t *ai_Array, size_t size );
int main(void)
{
const int8_t ai_Array[2][2] = { { 1, 2 }, { 3, 4 } };
int8_t returnValue = TwoDimArrayConst(( int8_t* const )ai_Array, sizeof( ai_Array) / sizeof( int8_t ));
printf( "%d\n", returnValue );
return 1;
}
static int8_t TwoDimArrayConst( const int8_t *ai_Array, size_t size )
{
int8_t test = 2;
for ( size_t i = 0; i < size; i++)
{
if (ai_Array[i] > 0)
{
test = 1;
break;
}
}
return test;
}
A run of the proposed code results in:
1
I'm trying to optimize access to some jump tables I have made, they are as follows:
int (*const usart_ctrl_table[USART_READ_WRITE_CLEAR])() =
{zg_usartCtrlRead, zg_usartCtrlWrite, zg_usartCtrlClr};
int (*const usart_frame_table[USART_READ_WRITE_CLEAR])() =
{zg_usartFrameRead, zg_usartFrameWrite, zg_usartFrameClr};
int (*const usart_trig_ctrl_table[USART_READ_WRITE_CLEAR])() =
{zg_usartTrigctrlRead, zg_usartTrigctrlWrite, zg_usartTrigctrlClr};
As you can see, the functions are for accessing a usart peripheral on a hardware level and are arranged in the table in the order of read/write/clear.
What I am attempting to do is have another jump table of jump tables, this way I can either run through initializing all the usart's registers in startup or simply change a single register later if desired.
i.e.
<datatype> (*usart_peripheral_table[<number of jump tables>])() =
{usart_ctrl_table, usart_frame_table, usart_trig_ctrl_table};
This way I can expose that table to my middleware layer, which will help maintain a standard across changing HALs, and also I can use a define to index this table i.e.
fn_ptr = usart_peripheral_table[CTRL_TABLE]
fn_ptr[WRITE](bitmask);
fn_ptr[READ](buffer);
As you may have already guessed, I am struggling to figure out how to construct this table. I figured it is one of two things:
Another simple array of pointers, as even a jump table itself is just an array of pointers. Hence my initialization would be:
const int* (*usart_peripheral_table[<number of jump tables])() =
{usart_ctrl_table, usart_frame_table, usart_trig_ctrl_table};
However this doesn't seem to be working. Then I thought:
An array of pointers to pointers. So I tried all kinds of combos:
const int**(*usart_perip...
const int**(usart_perip...
const int** (*usart_peripheral_table[<number of jump tables])() =
{&usart_ctrl_table, &usart_frame_table[0], usart_trig_ctrl_table};
Nothing seems to work. Do I need to store the address of the lower jump tables in yet another pointer before assigning that variable to a pointer-to-pointer array? i.e.
int* fn_ptr = usart_ctrl_table;
<dataytype>(*const usart_periph[<number>])() = {fn_ptr};
Thanks in advance, any help would be greatly appreciated.
MM25
EDIT:
const int** (*const peripheral_table[1])() =
{&usart_ctrl_table[0]};
const int** (*const peripheral_table[1])() =
{usart_ctrl_table};
The above both give the error "initialization from incomaptible pointer type", as do all other combinations I have tried
You might find that defining a typedef for your function pointers makes your code easier to read and maintain (although I’ve seen people recommend against it too):
#include <stdio.h>
#include <stdlib.h>
#define UART_RWC 3U
typedef int (*uart_ctl_func)(void);
int uart_read(void)
{
printf("Read.\n");
fflush(stdout);
return 0;
}
int uart_write(void)
{
printf("Write.\n");
fflush(stdout);
return(0);
}
int uart_clear(void)
{
printf("Clear.\n");
fflush(stdout);
return 0;
}
uart_ctl_func uart_ctl_jump_table[][UART_RWC] = {
{ uart_read, uart_write, uart_clear },
{ uart_read, uart_write, uart_clear }
};
int main(void)
{
uart_ctl_jump_table[0][1](); // Write.
uart_ctl_jump_table[1][0](); // Read.
uart_ctl_jump_table[1][2](); // Clear.
return EXIT_SUCCESS;
}
The next step might be to make the jump table a struct so you end up writing Uart_ctl_table.frame.read(), or to at least define an enum for the constants.
#include <stdio.h>
#include <stdlib.h>
#define UART_RWC 3U
typedef int (*uart_ctl_func)(void);
int uart_read(void)
{
printf("Read.\n");
fflush(stdout);
return 0;
}
int uart_write(void)
{
printf("Write.\n");
fflush(stdout);
return(0);
}
int uart_clear(void)
{
printf("Clear.\n");
fflush(stdout);
return 0;
}
typedef struct {
uart_ctl_func read;
uart_ctl_func write;
uart_ctl_func clear;
} uart_ctl_set_t;
typedef struct {
uart_ctl_set_t ctrl;
uart_ctl_set_t frame;
uart_ctl_set_t trig;
} uart_ctl_table_t;
const uart_ctl_table_t uart_ctl_table = {
.ctrl = { uart_read, uart_write, uart_clear },
.frame = { uart_read, uart_write, uart_clear },
.trig = { uart_read, uart_write, uart_clear }
};
int main(void)
{
uart_ctl_table.ctrl.write(); // Write.
uart_ctl_table.frame.read(); // Read.
uart_ctl_table.trig.clear(); // Clear.
return EXIT_SUCCESS;
}
Just add a * like you added [] when defining an array.
int zg_usartCtrlRead();
int zg_usartCtrlWrite();
int zg_usartCtrlClr();
int zg_usartFrameRead();
int zg_usartFrameWrite();
int zg_usartFrameClr();
int zg_usartTrigctrlRead();
int zg_usartTrigctrlWrite();
int zg_usartTrigctrlClr();
int (*const usart_ctrl_table[])() =
{zg_usartCtrlRead, zg_usartCtrlWrite, zg_usartCtrlClr};
int (*const usart_frame_table[])() =
{zg_usartFrameRead, zg_usartFrameWrite, zg_usartFrameClr};
int (*const usart_trig_ctrl_table[])() =
{zg_usartTrigctrlRead, zg_usartTrigctrlWrite, zg_usartTrigctrlClr};
int (* const * const usart_peripheral_table[])() =
{usart_ctrl_table, usart_frame_table, usart_trig_ctrl_table};
Usage:
usart_peripheral_table[1][2](5, 1, 3, 5, 6);
Btw, an empty parameter list on function declaration () means unspecified number and type of arguments. Do (void) if you want no arguments passed to your function.
This:
const int* (*usart_peripheral_table[<number of jump tables])();
Is an array of functions pointers that take unspecified number of arguments and return a pointer to constant integer.
This:
const int** (*usart_peripheral_table[<number of jump tables])()
Is an array of function pointers that take unspecified number of arguments and return a pointer to a pointer to a constant integer.
You can also go with a 2D array:
int (* const usart_peripheral_table_2d[][3])() = {
{
zg_usartCtrlRead, zg_usartCtrlWrite, zg_usartCtrlClr,
}, {
zg_usartFrameRead, zg_usartFrameWrite, zg_usartFrameClr,
}, {
zg_usartTrigctrlRead, zg_usartTrigctrlWrite, zg_usartTrigctrlClr,
},
};
But maybe you want to write accessor functions that will return a pointer to an array of functions. Nothing simpler!
#include <stddef.h>
int (*usart_ctrl_table_get(size_t idx))() {
return usart_ctrl_table[idx];
}
int (*usart_frame_table_get(size_t idx))() {
return usart_frame_table[idx];
}
int (*usart_trig_ctrl_table_get(size_t idx))() {
return usart_trig_ctrl_table[idx];
}
int (* const (* const usart_peripheral_table_indirect[])(size_t))() = {
usart_ctrl_table_get,
usart_frame_table_get,
usart_trig_ctrl_table_get,
};
Usage sample:
int main() {
usart_peripheral_table_indirect[2](1)();
}
I just started programming in C for school. I am being asked to do a program that uses a FIFO struct to resolve math problems. I got the folowing code on the internet for a FIFO, I just don't know how to use it. I tried a lot of things and I can't find anything useful on the internet or maybe that I just don't know the right thing to research but could you please help me? Thanks!
#include <stdio.h>
#include <stdlib.h>
typedef struct pile
{
int donnee;
struct pile *precedent;
} Pile;
void pile_push(Pile **p_pile, int donnee)
{
Pile *p_nouveau = malloc(sizeof *p_nouveau);
if (p_nouveau != NULL)
{
p_nouveau->donnee = donnee;
p_nouveau->precedent = *p_pile;
*p_pile = p_nouveau;
}
}
int pile_pop(Pile **p_pile)
{
int ret = -1;
if (p_pile != NULL)
{
Pile *temporaire = (*p_pile)->precedent;
ret = (*p_pile)->donnee;
free(*p_pile), *p_pile = NULL;
*p_pile = temporaire;
}
return ret;
}
void pile_clear(Pile **p_pile)
{
while (*p_pile != NULL)
{
pile_pop(p_pile);
}
}
I tried doing this:
int main()
{
int return_val;
Pile pile;
pile_push(Pile, 5);
return_val = pile_pop(Pile);
printf(return_val);
}
and got this error:
expected expression before 'Pile'
too few arguments to function 'pile_push'
You have mixed up Pile and pile which is the issue with the first warning. The functions expect a pointer to a pointer to a Pile. That is: They update the value of a pointer, so they need to be passed a reference to a pointer. Your use of printf is also wrong.
int main()
{
int return_val;
Pile *pile = NULL;
pile_push(&pile,5);
return_val = pile_pop(&pile);
printf("return_val is: %d\n",return_val);
}
I have written a straightforward C code that uses an engine to run two different algorithms depending on user input. It uses function pointers to the algorithm methods and objects. There is a nasty memory bug somewhere that I can not track down, so maybe I am allocating memory in the wrong way. What is going wrong?
Below is (the relevant parts of) a minimal working example of the code.
main.c
#include "engine.h"
int main()
{
char *id = "one";
Engine_t eng;
Engine_init(&eng);
Engine_select_algorithm(eng, id);
Engine_run(eng);
}
engine.h
typedef struct _Engine *Engine_t;
engine.c
#include "engine.h"
#include "algorithm_one.h"
#include "algorithm_two.h"
typedef struct _Engine
{
void *p_algorithm;
void (*init)(Engine_t);
void (*run)(Engine_t);
} Engine;
void Engine_init(Engine_t *eng)
{
*eng = malloc(sizeof(Engine));
(*eng)->p_algorithm = NULL;
}
void Engine_select_algorithm(Engine_t eng, char *id)
{
if ( strcmp(id, "one") == 0 )
{
eng->init = Algorithm_one_init;
eng->run = Algorithm_one_run;
}
else if ( strcmp(id, "two") == 0 )
{
eng->init = Algorithm_two_init;
eng->run = Algorithm_two_run;
}
else
{
printf("Unknown engine %s.\n", id); exit(0);
}
eng->init(eng);
}
void Engine_run(Engine_t eng)
{
eng->run(eng);
}
void Engine_set_algorithm(Engine_t eng, void *p)
{
eng->p_algorithm = p;
}
void Engine_get_algorithm(Engine_t eng, void *p)
{
p = eng->p_algorithm;
}
algorithm_one.h
typedef struct _A_one *A_one_t;
algorithm_one.c
#include "engine.h"
#include "algorithm_one.h"
typedef struct _A_one
{
float value;
} A_one;
void Algorithm_one_init(Engine_t eng)
{
A_one_t aone;
aone = malloc(sizeof(A_one));
aone->value = 13.0;
//int var = 10;
Engine_set_algorithm(eng, &aone);
}
void Algorithm_one_run(Engine_t eng)
{
A_one_t aone;
Engine_get_algorithm(eng, &aone);
printf("I am running algorithm one with value %f.\n", aone->value);
// The code for algorithm one goes here.
}
The code for algorithm_two.h and algorithm_two.c are identical to the algorithm one files.
There must be a memory bug involved, because the code runs as given, but if I uncomment the
//int var = 10;
line in algoritm_one.c the code crashes with a segmentation fault.
You pass the wrong thing to Engine_set_algorithm. You are passing the address of a local variable rather than the address of the algorithm. You need to write:
Engine_set_algorithm(eng, aone);
And also Engine_get_algorithm is wrong. You are passed a pointer by value and modify that pointer. So the caller cannot see that modification. You need it to be:
void Engine_get_algorithm(Engine_t eng, void **p)
{
*p = eng->p_algorithm;
}
I think your code would be easier if you defined a type to represent an algorithm. That type would be just a void*, but it would make the code much easier to read. What's more, I would make Engine_get_algorithm return the algorithm.
algorithm Engine_get_algorithm(Engine_t eng)
{
return eng->p_algorithm;
}
void Engine_set_algorithm(Engine_t eng, algorithm alg)
{
eng->p_algorithm = alg;
}
I define a structure in a header file like so:
typedef struct {
void *data;
} point;
I want to keep other people from accessing *data directly, so I thought I'd declare the structure in the .c file instead and use something like extern typedef struct point; in the header file. That doesn't work however.
What's the best way to achieve this?
In your (public) header file:
typedef struct point point;
In your .c file:
struct point
{
void *data;
};
Note that users of your code will no longer be able to create a point on the stack, as the compiler doesn't know how big it is. You may have to provide a point_create() function which allocates memory and returns its address to the caller.
Use C++
Since jokes seem not be allowed here is the pure C version.
As another commenter pointed out if you really want to protect your internals from users of your Api you have seen and used plenty of such Apis. This Apis are e.g. the Windows or Linux user mode Apis. There you create kernel objects to which you never shall have access to. The Apis to deal with kernel objects use a synthetic construct called handle which is not simply a pointer to your own object but instead it is an index to an array where the kernel has stored the relevant meta data for your object.
You can use the same idea for your Apis as well.
Here for example is a C-Style public Api:
// Public.h
#include <stdlib.h>
typedef enum
{
None = 0,
PointType = 1
} Types;
typedef int Handle;
Handle CreateType(Types type);
int DeleteType(Handle object);
void IncrementX(Handle point);
void PrintPoint(Handle point);
As you can see you have generic methods which create and delete your objects which are defined here in an enum. Your methods which use the object will then need to lookup the integer handle to get the meta data object where the real data is stored.
This design is not very efficient if the objects you manage are small since for every object a second object is need which stores the object type, handle value and the pointer to the real data.
But you get much stronger safety guarantees such as
Type safety
Invalid handles are easy to find
Double free is impossible since you can manage the free state in the meta object
A typical usage of your Api might look like this:
Handle h = CreateType(PointType);
IncrementX(h);
IncrementX(h);
PrintPoint(h);
DeleteType(h);
And there is the super secret implementation in private.cpp where the Handle lookup array and some helper methods exist:
// Private.C
#include "stdafx.h"
#include <stdlib.h>
#include <Windows.h> // for ZeroMemory
#include "Public.h"
typedef struct
{
LPVOID pData;
Types type;
Handle handle;
} HandleInfo;
typedef struct
{
int x;
int y;
} Point;
HandleInfo *pAllocated;
int HandleBuffer = 0xffff;
unsigned char bInit = 0;
HandleInfo *GetFreeHandle()
{
int i;
if( !bInit )
{
pAllocated = (HandleInfo *) malloc(sizeof(HandleInfo)*HandleBuffer);
bInit = 1;
ZeroMemory(pAllocated, sizeof(HandleInfo)*HandleBuffer);
}
for(i=0; i<HandleBuffer; i++)
{
HandleInfo *pInfo = (pAllocated+i);
if( 0 == pInfo->handle )
{
pInfo->handle = i+1;
return pInfo;
}
}
return NULL;
}
HandleInfo * GetHandleInfo(Handle h)
{
if( h <= 0 || h >= HandleBuffer-1)
{
return NULL;
}
return (pAllocated+h-1);
}
Handle CreateType(Types typeId)
{
HandleInfo *pInfo;
pInfo = GetFreeHandle();
if( NULL == pInfo )
{
return -1;
}
pInfo->type = typeId;
switch(typeId)
{
case PointType:
pInfo->pData = malloc(sizeof(Point));
ZeroMemory(pInfo->pData, sizeof(Point));
break;
}
return pInfo->handle;
}
int DeleteType(Handle object)
{
HandleInfo *pInfo = GetHandleInfo(object);
if( NULL == pInfo )
{
return -1;
}
if( pInfo->handle != 0 )
{
free(pInfo->pData);
pInfo->pData = NULL;
pInfo->handle = 0;
return 1;
}
else
{
return 0; // Handle was already closed
}
}
void *GetObjectOfCorrectType(Handle object, Types type)
{
HandleInfo *p = GetHandleInfo(object);
if( p == NULL )
{
return NULL;
}
if( p->type != type)
{
return NULL; // handle has wrong object type
}
return p->pData;
}
void IncrementX(Handle point)
{
Point *pPoint = (Point *) GetObjectOfCorrectType(point, PointType);
if( pPoint == NULL )
{
return;
}
pPoint->x++;
}
void PrintPoint(Handle point)
{
Point *pPoint = (Point *) GetObjectOfCorrectType(point, PointType);
if( pPoint == NULL )
{
return;
}
printf("Point has x: %d y: %d", pPoint->x, pPoint->y);
}
Yours,
Alois Kraus
This is the pointer to implementation or pimpl idiom. See http://en.wikibooks.org/wiki/C++_Programming/Idioms#Pointer_To_Implementation_.28pImpl.29 for a tutorial for C++, but the idea should work in C as well.
typedef struct {
/* private members; don't access directly */
void *data;
} point;
You can have separate public header and private header files. Some libraries have conventions for this:
Xt (X11) -> header.h and headerP.h, e.g: X11/Vendor.h vs X11/VendorP.h
Qt -> header.h vs private/header_p.h, e.g: qapplication.h vs private/qapplication_p.h
If you do not want to use the declaration method (because you want the library user to access other members of your struct, for example) it is convention to prepend private member with an underscore, like this:
typedef struct {
void * _data;
} point;
Of course people could still access _data if they would really want to (just like people can access private data in C++ by adding a #define private public before their includes) but that is their own responsibility; at least you have indicated that they shouldn't do that if they want your library to behave as it should.
I use this approach in order to let client alloc the module instance in his STACK.
struct module_private {
int data;
}
typedef uint8_t module_t [sizeof (struct module_private) ];
Client will be able to see private struct content, but not access it without doing a cast that he shouldn't.
Use the following workaround:
#include <stdio.h>
#define C_PRIVATE(T) struct T##private {
#define C_PRIVATE_END } private;
#define C_PRIV(x) ((x).private)
#define C_PRIV_REF(x) (&(x)->private)
struct T {
int a;
C_PRIVATE(T)
int x;
C_PRIVATE_END
};
int main()
{
struct T t;
struct T *tref = &t;
t.a = 1;
C_PRIV(t).x = 2;
printf("t.a = %d\nt.x = %d\n", t.a, C_PRIV(t).x);
tref->a = 3;
C_PRIV_REF(tref)->x = 4;
printf("tref->a = %d\ntref->x = %d\n", tref->a, C_PRIV_REF(tref)->x);
return 0;
}
Result is:
t.a = 1
t.x = 2
tref->a = 3
tref->x = 4