I'm new to C and I'm trying to simulate an Undo functionality for a problem. I'm using generic vectors defined like this:
typedef void* Element;
typedef struct {
Element* elems;
int size;
int capacity;
} Vector;
For this, I created a function called "Copy" that should return me a copy of the vector I'm passing:
Vector* copyVector(Vector *v) {
Vector* rez;
rez = createVector();
int i;
for (i = 0; i < getSize(v); i++) {
Element el = getElem(v, i);
add(rez, el);
}
return rez;
}
It works when I call it everytime to save the "before" vector... like when I try to apply an add or remove on my current vector, I call this copy function first on another vector called undoVec like this:
undoVec = copyVector(v);
I checked and it works but when I call my undo function... which should do the reverse of the code before:
v = copyVector(undoVec);
It's not working anymore. Doesn't do anything. It wont modify my vector v... which is really just a pointer I think
void undoVector(Vector *v, Vector *undoVec)
What am I doing wrong? why wont this functionality work? I can paste more code or give more info if required, thanks.
void add(Vector *v, Element elem) {
if (v->size == v->capacity) {
isFull(v);
}
v->elems[v->size] = elem;
v->size++;
}
Element getElem(Vector *v, int pos) {
return v->elems[pos];
}
Use a stack to implement because stack has a top.
To elaborate on The Dark's comment:
Are you assigning v = copyVector(undoVec); in the undoVector function?
If so that will only change the value of the parameter inside
undoVector, not the value of the what ever you called the function
with.
If you have
void undoVector(Vector *v, Vector *undoVec)
{
v = copyVector(undoVec);
}
…
undoVec = copyVector(v);
…
undoVector(v, undoVec);
the parameter v in undoVector() is a different object from v outside of undoVector(), it's just a copy that has initially the same value; thus, the v = copyVector(undoVec) only changes the value of the parameter v in undoVector(), but leaves untouched the independent v outside.
To achieve what you want, make it
void undoVector(Vector **v, Vector *undoVec)
{
*v = copyVector(undoVec);
}
…
undoVec = copyVector(v);
…
undoVector(&v, undoVec);
or - more similar to copyVector() and simple -
Vector *undoVector(Vector *undoVec)
{
return copyVector(undoVec);
}
…
undoVec = copyVector(v);
…
v = undoVector(undoVec);
or - most simple -
undoVec = copyVector(v);
…
v = copyVector(undoVec);
Related
TL;DR What should the type of x be if x = x(); is valid in C?
The whole story:
I am working on a simple game with multiple scenes. At first my code looked like this:
enum {kSCENE_A, kSCENE_B} ecene = kSCENE_A;
int main() {
while(1) {
switch(scene) {
case kSCENE_A:
// Renders scene a
// And possibly modifies `scene`
break;
case kSCENE_B:
// Renders scene b
// And possibly modifies `scene`
break;
}
}
}
However the main function is too verbose. I extracted the rendering part into different functions, but the switch still makes the code ugly. I defined a scene_map for this:
typedef enum {
kSCENE_A,
kSCENE_B,
kN_SCENES
} Scene;
Scene RenderSceneA();
Scene RenderSceneB();
int main() {
Scene scene = kSCENE_A;
Scene (*scene_map[kN_SCENES])();
scene_map[kSCENE_A] = SceneA;
scene_map[kSCENE_B] = SceneB;
while(1) scene = scene_map[scene]();
}
But I wonder if it would be possible in C that I write the code in this, or some similar way:
SomeType RenderSceneA();
SomeType RenderSceneB();
int main() {
SomeType scene = RenderSceneA;
while(1) scene = scene();
}
So what type should SomeType be, or can I only use void * for it? If the latter is true, how can I write this code in a clear manner than demonstrated in the second code block?
Here's a solution that will solve the problem. Note that it uses void (*)(void) as a generic function pointer type, as opposed to void * which isn't guaranteed to work for function pointers:
#include <stdio.h>
void (*f(void))(void);
void (*g(void))(void);
void (*f(void))(void)
{
printf("This is f.\n");
return (void (*)(void)) g;
}
void (*g(void))(void)
{
printf("This is g.\n");
return (void (*)(void)) f;
}
#define SRCALL(p) ((void (*(*)(void))(void)) p())
int main(void)
{
void (*(*p)(void))(void);
p = f;
p = SRCALL(p);
p = SRCALL(p);
p = SRCALL(p);
return 0;
}
The function pointer casts are ugly, so I encapsulated them in the macro SRCALL (self-ref-call). The output is:
This is f.
This is g.
This is f.
I'm currently creating a program to interpolate linear regressions on missing entries in a time series. IE Col 2 Row 20-30 is missing the program would take col 2 row 19 (for instance 10) and col 2 row 30 (20) then fill in the NULL values linearly ie 11, 12, 13. I have multiple columns which have NULL values, so to do this I want to create a struct
struct missingPoint
{
double lastVal;
struct node * ptrtoLast;
int missingVals;
};
struct point
{
double col1;
double col2;
double col3;
};
typdef struct point Tick;
typedef struct node
{
Tick tick;
struct node * next;
} Node;
typedef Node * List;
So the idea is to write a prototype then a function which takes *ptrtoList->tick.colx as an argument as well as the missingPoint struct then I can iterate it the col and fill in the missing time series data, it iterates the column storing ptrs to nodes which contain non-NULL entries for the Col, when it hits a NULL val, it has the ptr to the last node with non-null val, it iterates until it gets a non-Null value again then using the ptr it has stored in memory it iterates back through and replaces the Null values with a linear regression between the two poitns. But I don't know how I can specify a double which occurs inside a struct which is pointed to by another struct for a function and function prototype, with that function I could just call the function for every column I have, without it I'd have to hardcode quite a bit which I'd like to avoid. Any advice would be greatly appreciated.
So the function would be like this, this currently has the column hard coded, I'd like to pass the column number as an argument so that I can multithread it, and call the function multiple times since the matrices I'm looking at are quite big, and because I'd like to practice concurrent programming:
void crawlOne(List *plist)
{
Node * last;
double lastVal, tmp;
int i, count = 0;
Node * pnode = *plist;
while(pnode != NULL)
{
last = pnode->next;
pnode = pnode->next;
if(pnode->tick.col1=NULL)
{
while(pnode->tick.col1=NULL)
{
count ++;
pnode = pnode->next;
}
tmp = lastVal-pnode->tick.col1;
pnode = last;
for(i=0;i<count;i++)
{
pnode = pnode->next;
pnode->tick.col1 = lastVal + i*(tmp/count);
i++;
}
}
}
}
Generally: Just define the function multiple times. No, C doesn't have templates.
The best: Generalize your data by providing an interface to manipulate it via function pointers - such interface is typically a virtual table. In your case a single function pointer to access the underlying data by a read/write handle looks enough. This effectively pulls the variant/changing/non-constant parts of the function into a different place. Allow users to pass an additional generic argument so that users can pass custom context:
void crawlOne(List *plist, double *(*getcol)(void *arg, struct point *p), void *arg)
{
// tmp = lastVal-pnode->tick.col1;
double tmp = *getcol(arg, &lastVal-pnode->tick);
...
// pnode->tick.col1 = lastVal + i*(tmp/count);
*getcol(arg, &pnode->tick) = lastVal + i*(tmp/count);
...
}
double *point_getCol1(void *arg, struct point *p) {
return &p->col1;
}
double *point_getCol2(void *arg, struct point *p) {
return &p->col2;
}
double *point_getCol3(void *arg, struct point *p) {
return &p->col3;
}
int main() {
crawlOne(plist, point_getCol2, NULL);
crawlOne(plist, point_getCol3, NULL);
}
In your case you can pass offsetof to members in point and dereference a pointer to double* at proper positions. This is not flexible and invites bugs, because it doesn't statically check types:
void crawlOne(List *plist, size_t coloffset)
{
...
// tmp = lastVal-pnode->tick.col1;
double tmp = *(double*)((char*)&lastVal-pnode->tick + coloffset);
...
// pnode->tick.col1 = lastVal + i*(tmp/count);
*(double*)((char*)&pnode->tick + coloffset) = lastVal + i*(tmp/count);
...
}
int main() {
crawlOne(plist, offsetof(struct point, col1));
crawlOne(plist, offsetof(struct point, col2));
}
It's common to use a macro to ease up defining the function multiple times (only do if you really know what you are doing). Such tends to become hard to maintain, and is hard to debug:
#define DECLARE_CRAWL_ONE(FUNC, MEMBER) \
void FUNC(List *plist) \
{ \
/* tmp = lastVal-pnode->tick.col1; */ \
double tmp = lastVal-pnode->tick.MEMBER; \
... \
/* pnode->tick.col1 = lastVal + i*(tmp/count); */ \
lastVal-pnode->tick.MEMBER = lastVal + i*(tmp/count); \
... \
}
DECLARE_CRAWL_ONE(crawlOnecol1, col1)
DECLARE_CRAWL_ONE(crawlOnecol2, col2)
DECLARE_CRAWL_ONE(crawlOnecol2, col2)
So to summarize:
You have a function crawlOne(List *plist) that locates some objects of type struct point and does something to their col1 members.
You would like to have a function crawlSome(List *plist, int colnum) which:
when called as crawlSome(list, 1) operates on col1
when called as crawlSome(list, 2) operates on col2
and so on.
By far the cleanest approach, as John Bollinger suggested in a comment, is to redesign struct point to contain an array instead of three separate members:
struct point {
double col[3];
};
void crawlSome(List *plist, int colnum) {
// ...
pnode->tick.col[colnum] = ...;
}
This does mean that you have to change all existing code that uses struct point, which although straightforward could be tedious, but in the long term you have a cleaner and more efficient design. I would do this if at all possible.
If you really cannot change the definition of struct point (e.g. it is used by third-party code that you can't modify), then you can't avoid hardcoding the member names somehow, since the names don't exist at runtime. KamilCuk has suggested some options for this. Another that I might think of is to pull out the hardcoding into a "column selector" function, so that it only has to be done at one place in your program. It should not be too inefficient if it can be inlined.
inline double *select_column(struct point *pt, int colnum) {
switch (colnum) {
case 1: return &pt->col1;
case 2: return &pt->col2;
case 3: return &pt->col3;
default: abort(); // or perhaps return NULL;
}
}
void crawlSome(List *plist, int colnum) {
// ...
*select_column(&pnode->tick, colnum) = ...
}
This avoids the need to duplicate the code of crawlOne at all, with or without a macro.
If you want to reduce the repetition in defining select_column, you can use a macro with token pasting:
inline double *select_column(struct point *pt, int colnum) {
switch (colnum) {
#define DO(N) case N: return &pt->col ## N ;
DO(1)
DO(2)
DO(3)
#undef DO
default: abort(); // or perhaps return NULL;
}
}
If you want to make the selector a little nicer to use, you can wrap it in a macro:
#define COL(p, n) (*select_column(&(p), (n)))
void crawlSome(List *plist, int colnum) {
// ...
COL(pnode->tick, colnum) = ...;
}
Alternatively, a similar approach can be implemented with offsetof, though with the same lack of type checking that KamilCuk points out:
#include <stddef.h>
const size_t col_offsets[3] = {
offsetof(struct point, col1),
offsetof(struct point, col2),
offsetof(struct point, col3)
};
#define COL(p, n) (*(double *)((char *)&(p) + col_offsets[(n)]))
I am trying to create a small fixed size list of string, int tuples. A fixed size array of structs seemed like the way to go, but when manipulating the array entries, I constantly run into memory errors. What I've tried so far:
public struct S {
public string a;
public int b;
public S (string a, int b) {
this.a = a;
this.b = b;
}
}
public class Test {
public S arr[5];
public static void main () {
var test = new Test ();
test.arr[0].a = "hi";
test.arr[0].b = 5;
/* alternatively: */
//test.arr[0] = S ("hi", 5);
}
}
I have looked into the compiled C code, but I am not really familiar with C.
I read everything I found about vala structs and arrays of structs, but the little bit that's out there didn't enlighten me either.
The fixed size array seems to get initialized with "empty" structs, do I need to initialize it beyond that, somehow?
What am I misunderstanding about arrays of structs here?
Is there an alternative way to implement a fixed size list of string, int tuples? Are arrays of structs not suited for that?
Any help is greatly appreciated! It seems like such a simple task, but I've been struggling with it for days now :/ ...
First, you can make the C code quite a bit simpler by specific "Compact" on the class and disabling the type on the struct:
[CCode(has_type_id = false)]
public struct S {
public string a;
public int b;
public S (string a, int b) {
this.a = a;
this.b = b;
}
}
[Compact]
public class Test {
public S arr[5];
public static void main () {
var test = new Test ();
test.arr[0].a = "hi";
test.arr[0].b = 5;
/* alternatively: */
//test.arr[0] = S ("hi", 5);
}
}
Not a full answer, but it seems like there is a problem in the compiler generated destruction code:
void test_free (Test* self) {
_vala_array_destroy (self->arr, 5, (GDestroyNotify) s_destroy);
g_slice_free (Test, self);
}
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
if ((array != NULL) && (destroy_func != NULL)) {
int i;
for (i = 0; i < array_length; i = i + 1) {
if (((gpointer*) array)[i] != NULL) {
destroy_func (((gpointer*) array)[i]);
}
}
}
}
Note how the array parameter (which is of type gpointer, but was casted from an S[], namely arr) is casted to a gpointer* before the destroy_func () is called on it.
That would be fine if arr were a dynamic array, but it isn't.
If I modify the compiler output by hand everything works fine:
static void _vala_array_destroy (S* array, gint array_length, GDestroyNotify destroy_func) {
if ((array != NULL) && (destroy_func != NULL)) {
int i;
for (i = 0; i < array_length; i = i + 1) {
if (&array[i] != NULL) {
destroy_func (&array[i]);
}
}
}
}
The destroy function (destroy_func aka s_destroy) is now called on a valid S* (the address of the struct inside the array).
So it seems to me that you have discovered a compiler bug.
PS: Using a dynamic array works just fine, I would either do that or use some higher level data type like a Gee.ArrayList instead of a static array.
I have this call on a file called 'PlayBoard.c':
MoveSucc = putBoardSquare(theBoard, getX, getY, nextTurn);
Where 'theBoard' is a pointer to struct Board. Inside the function I am changing the board's size by referencing the pointer to ANOTHER Board struct, a bigger one. Will it change 'theBoard' on 'PlayBoard.c', where MoveSucc is invoked?
EDIT: putBoardSquare is defined in another source file
EDIT: I've added the relevant functions
Boolean putBoardSquare(BoardP theBoard, int X, int Y, char val)
{
if (val != 'X' && val != 'O')
{
reportError(BAD_VAL);
return FALSE;
}
if (X<0 || Y<0)
{
reportError(OUT_OF_BOUND);
return FALSE;
}
if (X>theBoard->height || Y>theBoard->width)
{
theBoard = expandBoard(theBoard, X,Y);
}
printf("BOARD SIZE IS %d*%d\n",theBoard->height,theBoard->width);
if (theBoard->board[X][Y] == 'X' || theBoard->board[X][Y] == 'Y' )
{
reportError(SQUARE_FULL);
return FALSE;
}
if (val != turn)
{
reportError(WRONG_TURN);
return FALSE;
}
theBoard->board[X][Y] = val;
printf("PUT %c\n",theBoard->board[X][Y]);
changeTurn(val);
return TRUE;
}
static BoardP expandBoard(ConstBoardP theBoard, int X, int Y)
{
int newWidth = theBoard->width;
int newHeight = theBoard->height;
if (X>theBoard->height)
{
newHeight = (newHeight+1) * 2;
}
if (Y>theBoard->width)
{
newWidth = (newWidth+1) * 2;
}
BoardP newBoard = createNewBoard(newWidth,newHeight);
copyBoard(theBoard,newBoard);
printf("RETUNRNING NEW BOARD OF SIZE %d*%d\n",newHeight,newWidth);
return newBoard;
}
As you can see, when the user tries to place 'X' or 'O' outside the board, it needs to be expanded which happens (I know cause I've printed new board's size in expandBoard() and in putBoardSquare()). But the pointer in 'PlayBoard.c' doesn't seem to change anyway....
My question: how can I change the pointer of a struct passed as an argument to another function? In 'PlayBoard.c' I pass one struct as an argument, and I want putBoardSquare to refrence it to another struct, which will take effect in PlayBoard.c as well.
Am I clear?
EDIT
theBoard = expandBoard(theBoard, X,Y);
This assignment only changes a local variable. You'll have to add one level of indirection, as in:
MoveSucc = putBoardSquare(&theBoard, getX, getY, nextTurn);
Boolean putBoardSquare(BoardP *theBoard, int X, int Y, char val)
{
/* ... */
*theBoard = expandBoard(theBoard, X,Y);
/* ... */
}
Your question is confusing (perhaps you should post the code you have), but the error you have is cause simply by the definition of the struct not being available in PlayBoard.c. For instance, if you only have
struct foo;
void foo(struct foo *foov) { ... }
without a definition of foo available, as in
struct foo { int a; ... }
then you won't be able to access the members of the structure (see "opaque type").
If I understand correctly and you want to change where theBoard points to, you need to define it as a pointer to pointer, not as pointer.
MoveSucc = putBoardSquare(&theBoard, getX, getY, nextTurn);
and change the parameter in putBoardSquare() to ** and when you set the pointer do it like (assuming x is a pointer):
*theBoard = x;
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