Timing behavior of null pointers in C - c

The below is mostly tested for Microsoft CL Version 17.00.50727.1 on Windows 7, but I see something similar with g++. I'm quite sure that the logical function is correct. The question is only about the timing.
Essentially I have a function that dynamically returns new "blocks" of data as needed. If it runs out of space in its "page", it makes a new page.
The purpose of the blocks is to match incoming data keys. If the key is found, that's great. If not, then a new data key is added to the block. If the block runs out of space, then a new block is created and linked to the old one.
The code works whether or not the block-making function explicitly sets the "next" pointer in the new block to NULL. The theory is that calloc() has set the content to 0 already.
The first odd thing is that the block-making function takes about 5 times(!) longer to run when that "next" pointer is explicitly set to NULL. However, then that is done, then the timing of the overall example behaves as expected: It takes linearly longer to match a new key, the more entries there are in the key list. The only difference occurs when a key is added which causes a new block to be fetched. The overhead of doing that is similar to the time taken to call the block-making function.
The only problem with this is that the block-making function is unacceptably slow then.
When the pointer is NOT explicitly set to NULL, then the block-making function becomes nice and fast -- maybe half to a quarter of the key-matching function, instead of as long or even longer.
But then the key-matching function starts to exhibit odd timing behavior. It does mostly increase linearly with the number of keys. It still has jumps at 16 and 32 keys (since the list length is 16). But it also has a large jump at key number 0, and it has large jumps at keys number 17, 33 etc.
These are the key numbers when the program first has to look at the "next" pointer. Apparently it takes a long time to figure out that the 0 value from calloc is really a NULL pointer? Once it knows this, the next times are faster.
The second weird thing is that the effect goes away if the data struct consists exclusively of the key. Now the jumps at 0, 17, 33 etc. go away whether or not the "next" pointer is explicitly set to NULL. But when "int unused[4]" is also in the struct, then the effect returns.
Maybe the compiler (with option /O2 or with -O3 for g++) optimizes away the struct when it consists of a single number? But I still don't see why that would affect the timing behavior in this way.
I've tried to simplify the example as much as I could from the real code, but I'm sorry that it's still quite long. It's not that complicated, though.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
void timer_start(int n);
void timer_end(int n);
void print_times();
// There are pages of blocks, and data entries per block.
// We don't know ahead of time how many there will be.
// GetNextBlock() returns new blocks, and if necessary
// makes new pages. MatchOrStore() goes through data in
// a block to try to match the key. It won't ever match
// in this example, so the function makes a new data entry.
struct dataType
{
// Surprise number 1: If the line with "unused" is
// commented out, things behave as expected, even if
// Surprise number 2 is in effect.
int unused[4];
int key;
};
#define DATA_PER_BLOCK 16
struct blockType
{
char nextEntryNo;
struct dataType list[DATA_PER_BLOCK];
struct blockType * next;
};
struct pageType
{
int nextBlockNo;
struct blockType * list;
struct pageType * next;
struct pageType * prev;
};
struct blockType * GetNextBlock();
void MatchOrStore(
struct dataType * dp,
struct blockType * bp);
struct pageType * pagep;
int main(int argc, char * argv[])
{
pagep = (struct pageType *) 0;
struct dataType data;
for (int j = 0; j < 50000; j++)
{
struct blockType * blockp = GetNextBlock();
// Make different keys each time.
for (data.key = 0; data.key < 40; data.key++)
{
// One timer per key number, useful for statistics.
timer_start(data.key);
MatchOrStore(&data, blockp);
timer_end(data.key);
}
}
print_times();
exit(0);
}
#define BLOCKS_PER_PAGE 5000
struct blockType * GetNextBlock()
{
if (pagep == NULL ||
pagep->nextBlockNo == BLOCKS_PER_PAGE)
{
// If this runs out of page space, it makes some more.
struct pageType * newpagep = (struct pageType *)
calloc(1, sizeof(struct pageType));
newpagep->list = (struct blockType *)
calloc(BLOCKS_PER_PAGE, sizeof(struct blockType));
// I never actually free this, but you get the idea.
newpagep->nextBlockNo = 0;
newpagep->next = NULL;
newpagep->prev = pagep;
if (pagep)
pagep->next = newpagep;
pagep = newpagep;
}
struct blockType * bp = &pagep->list[ pagep->nextBlockNo++ ];
// Surprise number 2: If this line is active, then the
// timing behaves as expected. If it is commented out,
// then presumably calloc still sets next to NULL.
// But the timing changes in an unexpected way.
// bp->next = (struct blockType *) 0;
return bp;
}
void MatchOrStore(
struct dataType * dp,
struct blockType * blockp)
{
struct blockType * bp = blockp;
while (1)
{
for (int i = 0; i < bp->nextEntryNo; i++)
{
// This will spend some time traversing the list of
// blocks, failing to find the key, because that's
// the way I've set up the data for this example.
if (bp->list[i].key != dp->key) continue;
// It will never match.
return;
}
if (! bp->next) break;
bp = bp->next;
}
if (bp->nextEntryNo == DATA_PER_BLOCK)
{
// Once in a while it will run out of space, so it
// will make a new block and add it to the list.
timer_start(99);
struct blockType * bptemp = GetNextBlock();
bp->next = bptemp;
bp = bptemp;
timer_end(99);
}
// Since it didn't find the key, it will store the key
// in the list here.
bp->list[ bp->nextEntryNo++ ].key = dp->key;
}
#define NUM_TIMERS 100
#ifdef _WIN32
#include <time.h>
LARGE_INTEGER
tu0[NUM_TIMERS],
tu1[NUM_TIMERS];
#else
#include <sys/time.h>
struct timeval
tu0[NUM_TIMERS],
tu1[NUM_TIMERS];
#endif
int ctu[NUM_TIMERS],
number[NUM_TIMERS];
void timer_start(int no)
{
number[no]++;
#ifdef _WIN32
QueryPerformanceCounter(&tu0[no]);
#else
gettimeofday(&tu0[no], NULL);
#endif
}
void timer_end(int no)
{
#ifdef _WIN32
QueryPerformanceCounter(&tu1[no]);
ctu[no] += (tu1[no].QuadPart - tu0[no].QuadPart);
#else
gettimeofday(&tu1[no], NULL);
ctu[no] += 1000000 * (tu1[no].tv_sec - tu0[no].tv_sec )
+ (tu1[no].tv_usec - tu0[no].tv_usec);
#endif
}
void print_times()
{
printf("%5s %10s %10s %8s\n",
"n", "Number", "User ticks", "Avg");
for (int n = 0; n < NUM_TIMERS; n++)
{
if (number[n] == 0)
continue;
printf("%5d %10d %10d %8.2f\n",
n,
number[n],
ctu[n],
ctu[n] / (double) number[n]);
}
}

Related

How to implement a 'Pop' function that returns the "popped" element (i.e the data/value) ? (linked list stacks)

Confused as to how to implement a single function that would at the same time pop the element and return it as return value.
So far all I've seen are pop functions that return a pointer to the new head of the stack.
Here's a start, but...
#define VALUE int
typedef struct node_t {
VALUE item;
struct node_t *next;
} node;
.
.
.
// Function
VALUE pop(node *stack_head) {
// Used to store the node we will delete
node *deleteNode = stack_head;
// Error Checking // <<====== (btw, is this actually necessary ?)
if (!deleteNode || !stack_head) {
if (!stack_head) fprintf(stderr, "\nPop failed. --> ...\n");
if (!deleteNode) fprintf(stderr, "\nPop Failed. --> ...\n");
return 0;
}
// Storing the value in a variable
VALUE popped_item = stack_head->item;
// Updating the head
stack_head = stack_head->next; <<====== THERE'S A PROBLEM HERE ! (i think)
// Freeing/Deleting the 'popped' node
free(deleteNode);
// Return 'popped' value
return popped_item;
}
.
.
.
stack_head = stack_head->next;
Doesn't actually change the address that the pointer stack_head (i.e the head of the stack) points to... and so the value is indeed returned for the first pop but subsequent pops return errors.
Yes because it is a local variable but then how would you change the actual pointer (the one that points to the head of the stack) to point to the new head of the stack?
The parameter stack_head is local to the function pop, so when you modify it the result is not visible outside of the function.
You need to pass the address of the variable you want to modify, then in the function you dereference the pointer parameter to change what it points to.
So change your function to this:
VALUE pop(node **stack_head) {
node *deleteNode = *stack_head;
if (!*stack_head) {
fprintf(stderr, "\nPop failed. --> ...\n");
return 0;
}
VALUE popped_item = (*stack_head)->item;
*stack_head = (*stack_head)->next;
free(deleteNode);
return popped_item;
}
And call it like this:
node *stack_head = NULL;
// do something to push onto the stack
VALUE v = pop(&stack_head);
Okay, this will be a pretty long digest, but hopefully worth it. You can see a testcase of the code I've presented as my conclusion here and obtain a modular version of the code here. My suggestion would be that you use a structure like this:
struct {
size_t top;
T value[];
}
The reason you probably shouldn't use classical linked lists for this (or anything, really) is covered by this video courtesy of Bjarne Stroustrup. The basis of the problem is that the majority of your overhead is in allocation and cache misses which don't occur so much when you keep everything in one allocation.
If I were to write this for convenient use, perhaps:
#define stack_of(T) struct { size_t top; T value[]; }
This should allow you to declare empty stacks fairly sensibly, like:
int main(void) {
stack_of(int) *fubar = NULL;
}
This is familiar enough to templates in other languages to work fairly well, and also not a hideous abuse of the preprocessor. I'm sure I've written a push_back function somewhere which we can adapt to this version of push which I've linked to externally as it's not important for the conclusion of this answer (bear with me here; we'll come back to that momentarily)...
So now we have stack_of(T) and push(list, value) which we can use like:
int main(void) {
stack_of(int) *fubar = NULL;
push(fubar, 42);
push(fubar, -1);
}
The simplest solution for pop might be something like:
#define pop(list) (assert(list && list->top), list->value[--list->top]))
... but this does suffer a drawback we'll discuss later. For now we have as a testcase:
int main(void) {
stack_of(int) *fubar = NULL;
int x;
push(fubar, 42);
push(fubar, -1);
x = pop(fubar); printf("popped: %d\n", x);
x = pop(fubar); printf("popped: %d\n", x);
x = pop(fubar); printf("popped: %d\n", x);
}
... and as you'll see during debug the assert fails during execution telling us we've popped more than we've pushed... probably a good thing to have. Still, this doesn't actually reduce the size of the stack. To do that we actually need something more like push again, except we get rid of these lines:
list->top = y; \
list->value[x] = v; \
So there's an opportunity for refactoring. Thus I bring you operate():
#define operate(list, ...) { \
size_t x = list ? list->top : 0 \
, y = x + 1; \
if ((x & y) == 0) { \
void *temp = realloc(list, sizeof *list \
+ (x + y) * sizeof list->value[0]); \
if (!temp) \
return EXIT_FAILURE; \
list = temp; \
} \
__VA_ARGS__; \
}
Now we can redefine push in terms of operate:
#define push(list, v) operate(list, list->value[x] = v; list->top = y)
... and pop looks kind of like it did before, but with an invocation of operate on the end to cause list to shrink (from quadruple its size, for example when you've popped 3 elements off of a list of 4) to no larger than double its size.
#define pop(list) (assert(list && list->top), list->value[--list->top]); \
operate(list, )
Summing it all up, you can see a testcase of the code I've presented here and obtain a modular version of the code here...

Allocating memory for struct within a struct in cycle

I'm working on INI-style configuration parser for some project, and I gets next trouble.
I have 3 structures:
typedef struct {
const char* name;
unsigned tract;
int channel;
const char* imitation_type;
} module_config;
typedef struct {
int channel_number;
int isWorking;
int frequency;
int moduleCount;
} channel_config;
typedef struct {
int mode;
module_config* module;
channel_config* channel;
} settings;
And I have function for handling data in my INI-file (I working under inih parser): [pasted to pastebin cause too long]. Finally, in main(), I did the next:
settings* main_settings;
main_settings = (settings*)malloc(sizeof(settings));
main_settings->module = (module_config*)malloc(sizeof(module_config));
main_settings->channel = (channel_config*)malloc(sizeof(channel_config));
if (ini_parse("test.ini", handler, &main_settings) < 0) {
printf("Can't load 'test.ini'\n");
return 1;
}
In result, binary crashes with memory fault. I think (no, I KNOW), what I'm incorrectly allocating the memory in handler(), but I does not understand, where I do it wrong. I spent all night long trying to understand memory allocating, and I'm very tired, but now me simply interestingly, what I'm doing wrong, and HOW to force this working fine.
P.S. Sorry for ugly english
The problem seems to be related to the reallocation of your structs:
pconfig = (settings *) realloc(pconfig, (module_count + channel_count) * sizeof(channel_config));
pconfig->module = (module_config *) realloc(pconfig->module, module_count * sizeof(module_config));
pconfig->channel = (channel_config *) realloc(pconfig->channel, channel_count * sizeof(channel_config));
First of all, you must not reallocate the main settings struct. Since your handler will always be called with the original pconfig value, the reallocation of the module and channel arrays has no effect, and you'll access freed memory.
Also when reallocating the module and channel arrays you should allocate count + 1 elements, since the next invocation of handler might assign to the [count] slot.
So try to replace the three lines above with:
pconfig->module = (module_config *) realloc(pconfig->module, (module_count + 1) * sizeof(module_config));
pconfig->channel = (channel_config *) realloc(pconfig->channel, (channel_count + 1) * sizeof(channel_config));

Contents of array changing within a struct in C

I'm currently stumped on this problem I have.
I have this structure:
typedef struct corgi_entry {
unsigned pup; //Supposed to be hex
} corgi_entry, *Pcorgi_entry;
typedef struct corgi {
Pcorgi_entry *arrayCorgiHead;
} corgi, *Pcorgi;
I have this variables:
static corgi c1;
In an init function, I malloc my arrayCorgiHead
c1.arrayCorgiHead = (Pcorgi_entry *)malloc(sizeof(Pcorgi_entry) * corgiNumber));
The corgiNumber is just a placeholder, it can be however many, just the size of the index.
Given this, later on I'm running a loop. Every iteration of the loop, I'm given a corgi and an index from somewhere. If at that index it is null, I'm supposed to make a corgi and assign the pup data to be the same. If it's not null, I check the corgi I'm given with the corgi at the index to see if the pup match.
if(c1.arrayCorgiHead[index] == NULL){
corgi_entry newcorgi_entry = {pupnumber};
c1.arrayCorgiHead[index] = &newcorgi_entry;
printf("Corgi Made!, pup: %10x\n", c1.arrayCorgiHead[index]->pup); //For debug purposes
}
else{ //Not null
if(c1.arrayCorgiHead[index]->pup != given_corgi_pup){
printf("Corgi Found?, pup: %10x\n", c1.arrayCorgiHead[index]->pup); //For debug purposes
//Do stuff
}
}
Here's the problem. In the file where I give this code the "external" index/corgis, on my third entry I give it the same as the first:
Index: 1 Corgi{pup = 123}
Index: 2 Corgi{pup = 456}
Index: 1 Corgi{pup = 123}
For some reason, when it processes the third entry, it says that it doesn't match. I print out the corgi pup at the array index, and I get some really weird number that doesn't make any sense (9814008 or something). This random number changes every time I ./corgisim and whatnot.
I do not touch the array at any other point besides what's written here. Why would my data be changing after a loop iteration?
*edit: To clarify my last point, my printf statements goes
Corgi Made!, pup: 123
Corgi Made!, pup: 456
Corgi Found?, pup: 20138940139 (random number that changes every time I run my program)
This code has been abbreviated for the sake of clarity (and corgi-ed, I don't know if that makes things clearer or not. The numbness in my brain has driven me insane). As you may be able to tell from the code, I'm not very familiar with C.
Thanks!
Edit 2: Thanks guys, solution worked like a charm! Pretty long question for a pretty simple problem, but I'm glad I figured it out. Much appreciated.
Here is the problem:
corgi_entry newcorgi_entry = {pupnumber};
c1.arrayCorgiHead[index] = &newcorgi_entry;
Variable newcorgi_entry is a local variable, which is allocated on the stack. Therefore, once outside the variable's scope of declaration, you cannot rely on &newcorgi_entry as a valid memory address.
Here is the solution:
You should allocate the corgi_entry instance on the heap instead:
corgi_entry* newcorgi_entry = malloc(sizeof(corgi_entry));
newcorgi_entry->pup = pupnumber;
c1.arrayCorgiHead[index] = newcorgi_entry;
The problem is how you "allocate" memory:
corgi_entry newcorgi_entry = {pupnumber};
c1.arrayCorgiHead[index] = &newcorgi_entry;
Here, newcorgi_entry is allocated on the stack. Then you assign the address of that stack variable to your array. Problem is, as soon as your function runs out of scope that memory is free to be used by any other function and sooner or later gets overwritten by some other code.
There are two solutions: either allocate on the heap using malloc, or don't use pointers at all. The first solution looks like this:
Pcorgi_entry newcorgi_entry = malloc(sizeof(corgi_entry));
newcorgi_entry->pub = pubnumber;
c1.arrayCorgiHead[index] = newcorgi_entry;
For the second solution there are a few variations. Here's one:
typedef struct corgi_entry {
unsigned pup;
int inUse;
} corgi_entry, *Pcorgi_entry;
typedef struct corgi {
corgi_entry *arrayCorgiHead; // "Head" is the wrong name here, IMHO.
} corgi, *Pcorgi;
static corgi c1;
// calloc clears the memory to 0
c1.arrayCorgiHead = (corgi_entry *)calloc(corgiNumber, sizeof(corgi_entry));
if(!c1.arrayCorgiHead[index].inUse){
c1.arrayCorgiHead[index].pub = pubNumber
c1.arrayCorgiHead[index].inUse = 1;
printf("Corgi Made!, pup: %10x\n", c1.arrayCorgiHead[index].pup); //For debug purposes
}
else{
if(c1.arrayCorgiHead[index].pup != given_corgi_pup){
printf("Corgi Found?, pup: %10x\n", c1.arrayCorgiHead[index].pup); //For debug purposes
//Do stuff
}
}
I think the corgi struct and its variable are unnecessary. I'd do it like this instead:
typedef struct corgi_entry {
unsigned pup;
int inUse;
} corgi_entry;
static corgi_entry *corgis;
// calloc clears the memory to 0
corgis = (corgi_entry *)calloc(corgiNumber, sizeof(corgi_entry));
if(!corgis[index].inUse){
corgis[index].pub = pubNumber
corgis[index].inUse = 1;
printf("Corgi Made!, pup: %10x\n", corgis[index].pup); //For debug purposes
}
else{
if(corgis[index].pup != given_corgi_pup){
printf("Corgi Found?, pup: %10x\n", corgis[index].pup); //For debug purposes
//Do stuff
}
}
Yet another way would be if you define the "pubNumber" 0 to be illegal so you can us it as a sentinel instead:
typedef struct corgi_entry {
unsigned pup;
} corgi_entry;
static corgi_entry *corgis;
// calloc clears the memory to 0
corgis = (corgi_entry *)calloc(corgiNumber, sizeof(corgi_entry));
// pub number 0 is illegal, so it must be an unused entry
if(corgis[index].pub == 0) {
corgis[index].pub = pubNumber
printf("Corgi Made!, pup: %10x\n", corgis[index].pup); //For debug purposes
}
else{
if(corgis[index].pup != given_corgi_pup){
printf("Corgi Found?, pup: %10x\n", corgis[index].pup); //For debug purposes
//Do stuff
}
}

Program hangs with no output

I've been poring over this program for ages, and have no idea why it doesn't work. I'm reasonably sure it's doing everything right but instead of actually working it just hangs indefinitely after printing the first prompt, and I just can't figure out why. I'm pretty much at my wit's end now, so if any can suggest what I'm doing wrong, I'd be much obliged...
It's C99, and you'll need the mhash library to compile it (uses for the CRC32 calculation). It's pretty portable but I developed it on Linux. Do not run in a VM!
#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <mhash.h>
/* WARNING: Do not debug this program. Halting on breakpoints at the wrong
* time can be extremely hazardous. YOU HAVE BEEN WARNED. */
/* Structures used to define our layout. Note the careful use of volatile;
* we don't want the compiler optimising away part of the invocation. */
typedef struct
{
const char name[7]; /* sigil at focus */
volatile int target; /* summoning point */
volatile char invocation; /* current char of invocation */
} focus_t;
typedef struct node
{
const char name[4]; /* name of node */
focus_t* center; /* points to the evocation focus */
struct node* cw; /* clockwise binding ring */
struct node* ccw; /* counterclockwise binding ring */
struct node* star; /* next node of star */
const char* linkname; /* name of star linkage */
volatile uint32_t angel; /* protective angel for this node */
} node_t;
/* The pentacle nodes are circularly linked in both directions to form
* a binding perimeter. In addition, they are singly linked to form a
* classic 'daemon trap' five-pointed star. Each node points towards the
* evocation focus (but not the other way around!) to enforce the geometry
* we want. The design is based heavily on the Pentagram of Solomon. */
struct
{
focus_t focus;
node_t node[5];
}
S =
{
/* None of the symbols for the pentacle are in Unicode. So we have to make
* do with Latin transcriptions. */
.focus = { "SOLUZEN", 0 },
.node = {
[0] = { "TE", &S.focus, &S.node[1], &S.node[4], &S.node[2], "BELLONY" },
[1] = { "TRA", &S.focus, &S.node[2], &S.node[0], &S.node[3], "HALLIY" },
[2] = { "GRAM", &S.focus, &S.node[3], &S.node[1], &S.node[4], "HALLIZA" },
[3] = { "MA", &S.focus, &S.node[4], &S.node[2], &S.node[0], "ABDIA" },
[4] = { "TON", &S.focus, &S.node[0], &S.node[3], &S.node[1], "BALLATON" }
}
};
/* Name of spirit to summon --- rot13'd for safety.
* (#65 from Crowley's translation of SHEMHAMPHORASH.)
* This is Andrealphus, he that has dominion over menusuration, astronomy and
* geometry. He seems fairly non-threatening. */
const char spiritname[] = "NAQERNYCUHF";
int rot13(int c) { return 'A' + (((c - 'A') + 13) % 26); }
/* We invoke the following names around the circle as a protective measure.
* Strictly these should be in Hebrew script, but as the computer is a dumb
* instrument we're relying on the symbolism rather than the actual literal
* meaning themselves. Plus, working in RTL is a pain. */
const char* angels[] = {
"Kether", "Eheieh", "Metatron", "Chaioth ha-Qadesh",
"Rashith ha-Gilgalim", "Chokmah", "Jah", "Ratziel", "Auphanim",
"Masloth", "Binah", "Jehovah Elohim", "Tzaphkiel", "Aralim",
"Shabbathai", "Chesed", "El", "Tzadkiel", "Chasmalim", "Tzadekh",
"Geburah", "Elohim Gibor", "Khamael", "Seraphim", "Madim",
"Tiphareth", "Eloah Va-Daath", "Raphael", "Malachim", "Shemesh",
"Netzach", "Jehovah Sabaoth", "Haniel", "Elohim", "Nogah", "Hod",
"Elohim Sabaoth", "Michael", "Beni Elohim", "Kokab", "Yesod",
"Shaddai El Chai", "Gabriel", "Cherubim", "Levanah"
};
const int angelcount = sizeof(angels)/sizeof(*angels);
/* Place the next angel on the pentacle. */
static void updatepentacle()
{
static int angelnode = 0;
static int angelindex = 0;
const char* angel = angels[angelindex++];
angelindex %= angelcount;
/* Hash the angel's name to reduce its essence to 32 bits (which lets us
* copy the angel bodily into the pentacle node. */
uint32_t angelhash;
MHASH td = mhash_init(MHASH_CRC32);
mhash(td, angel, strlen(angel));
mhash_deinit(td, &angelhash);
S.node[angelnode].angel = angelhash;
angelnode = (angelnode + 1) % 5;
}
int main(int argc, const char* argv[])
{
/* Lock the evocation into memory, to prevent it from being paged out
* while the spirit has manifested --- which would be bad. */
int e = mlock(&S, sizeof(S));
if (e != 0)
{
fprintf(stderr, "Unable to lock evocation, refusing to run\n");
exit(1);
}
/* Actually perform the invocation: continually cycle the spirit's
* name into the evocation focus (while maintaining our pentacle
* integrity!) until something shows up in the target of the
* evocation focus. */
printf("Summoning...\n");
do
{
for (int i = 0; i < sizeof(spiritname)-1; i++)
{
S.focus.invocation = rot13(spiritname[i]);
updatepentacle();
usleep(100); /* don't CPU-starve our spirit */
}
}
while (S.focus.target == 0);
printf("Summoning successful! %d\n", S.focus.target);
/* Our spirit's arrived! Dismiss it immediately by using a null
* invocation. Keep going until the evocation focus remains empty.
* FIXME: a particularly mean spirit might find a way to hide. Until
* we can sort this out, only summon relatively benign ones. This is
* probably safe anyway, as when the process terminates the spirit's
* address space will be nuked, taking the spirit with it. */
printf("Dismissing...\n");
do
{
S.focus.target = 0;
for (int i = 0; i < 1000; i++)
{
S.focus.invocation = 0;
updatepentacle();
}
}
while (S.focus.target != 0);
printf("Done.\n");
return 0;
}
Incidentally, shouldn't there be a goetic tag?
Edit: Sorry I haven't gotten back earlier --- after I posted my query last night I ran some more tests and then my computer started making funny burning smells which didn't go away when I switched it off, so I spent the rest of the night tearing it down trying to find which part was faulty. (Didn't find anything.) I'm going to grab some sleep and get back to you. Thanks for the replies!
Edit: I'm posting this from a web café. My house has burnt down. Don't have time to post more but have to warn you: do not run this program for any reason! Really! Not joking! Have to go now, must find sanctuary somewhere---
Edit: 𝕳𝖔𝖈 𝖘𝖙𝖚𝖑𝖙𝖚𝖘 𝖒𝖊𝖚𝖘 𝖊𝖘𝖙. 𝕹𝖔𝖓 𝖎𝖓𝖙𝖊𝖗𝖕𝖔𝖓𝖊 𝖖𝖚𝖎 𝖓𝖔𝖓 𝖎𝖓𝖙𝖊𝖑𝖑𝖎𝖌𝖊𝖗𝖊.
Crux sacra sit mihi lux!
Nunquam draco sit mihi dux.
Vade retro Satana!
Nunquam suade mihi vana!
Sunt mala quae libas.
Ipse venena bibas!
You are definitely lacking a lot of evil features. You should switch to C++ and have a look at the Comp.lang.c++-FAQ on evil features.
I don't know enough about demons and angels, but you must be summoning them incorrectly, since nothing is changing S.focus.target for you.

External Functions and Parameter Size Limitation (C)

I am very much stuck in the following issue. Any help is very much appreciated!
Basically I have a program wich contains an array of structs and I am getting a segmentation error when I call an external function. The error only happens when I have more than 170 items on the array being passed.
Nothing on the function is processed. The program stops exactly when accessing the function.
Is there a limit for the size of the parameters that are passed to external functions?
Main.c
struct ratingObj {
int uid;
int mid;
double rating;
};
void *FunctionLib; /* Handle to shared lib file */
void (*Function)(); /* Pointer to loaded routine */
const char *dlError; /* Pointer to error string */
int main( int argc, char * argv[]){
// ... some code ...
asprintf(&query, "select mid, rating "
"from %s "
"where uid=%d "
"order by rand()", itable, uid);
if (mysql_query(conn2, query)) {
fprintf(stderr, "%s\n", mysql_error(conn2));
exit(1);
}
res2 = mysql_store_result(conn2);
int movieCount = mysql_num_rows(res2);
// withhold is a variable that defines a percentage of the entries
// to be used for calculations (generally 20%)
int listSize = round((movieCount * ((double)withhold/100)));
struct ratingObj moviesToRate[listSize];
int mvCount = 0;
int count =0;
while ((row2 = mysql_fetch_row(res2)) != NULL){
if(count<(movieCount-listSize)){
// adds to another table
}else{
moviesToRate[mvCount].uid = uid;
moviesToRate[mvCount].mid = atoi(row2[0]);
moviesToRate[mvCount].rating = 0.0;
mvCount++;
}
count++;
}
// ... more code ...
FunctionLib = dlopen("library.so", RTLD_LAZY);
dlError = dlerror();
if( dlError ) exit(1);
Function = dlsym( FunctionLib, "getResults");
dlError = dlerror();
(*Function)( moviesToRate, listSize );
// .. more code
}
library.c
struct ratingObj {
int uid;
int mid;
double rating;
};
typedef struct ratingObj ratingObj;
void getResults(struct ratingObj *moviesToRate, int listSize);
void getResults(struct ratingObj *moviesToRate, int listSize){
// ... more code
}
You are likely blowing up the stack. Move the array to outside of the function, i.e. from auto to static land.
Another option is that the // ... more code - array gets populated... part is corrupting the stack.
Edit 0:
After you posted more code - you are using C99 variable sized array on the stack - Bad IdeaTM. Think what happens when your data set grows to thousands, or millions, of records. Switch to dynamic memory allocation, see malloc(3).
You don't show us what listsize is, but I suppose it is a variable and not a constant.
What you are using are variable length arrays, VLA. These are a bit dangerous if they are too large since they usually allocated on the stack.
To work around that you can allocate such a beast dynamically
struct ratingObj (*movies)[listSize] = malloc(sizeof(*movies));
// ...
free(movies);
You'd then have in mind though that movies then is a pointer to array, so you have to reference with one * more than before.
Another, more classical C version would be
struct ratingObj * movies = malloc(sizeof(*movies)*listsize);
// ...
free(movies);

Resources