Winapi get Interlocked Singly Linked List Item, without Popping it - c

I use a WinApi native Single linked list, i have a code example like so, that creates singly linked list, and nsert some data there:
#include <Windows.h>
#include <stdio.h>
typedef struct Info
{
SLIST_ENTRY ItemEntry;
DWORD dwUserId;
} INFO,*PINFO;
int main()
{
PINFO pInfo1 = __aligned_malloc(sizeof(INFO));
pInfo1.dwUserId = 1;
PINFO pInfo2 = __aligned_malloc(sizeof(INFO));
pInfo2.dwUserId = 2;
PSLIST_HEADER pListHead = __aligned_malloc(sizeof(pListHead));
InitializeSListHead(pListHead);
InterlockedPushEntrySList(pListHead, &(pInfo1->ItemEntry));
InterlockedPushEntrySList(pListHead, &(pInfo2->ItemEntry));
PINFO pInfoFirst = InterlockedPopEntrySList(pListHead); // gets pInfo2 into pInfoFirst, and removes it from list
DebugBreak();
ExitProcess(0);
}
The thing is, that i don't need to pop the item, of course i can just insert it back, but that's really no needed overhead. I tried to access it like that:
PINFO pInfoFirst = (PINFO)&pListHead->Next;
But i get weird stuff in pInfoFirst. How can i do it?

Related

How do I determine the source of this memory change/corruption?

I am currently developing a Vulkan program that I anticipate to use as a game engine, but I am far from my goal. As a first step, I'm just trying to render a triangle using a list of dynamic structures to get data such as vertices and shaders. To work around platform specific hurdles, I'm using GLFW to create windows and Vulkan surfaces.
Right now I'm trying to load SPIR-V shaders from a file and use them to create VkShaderModules which I will use in my render pipeline. Currently, the abstracted part of my code starts like this:
main.c
#include "application.h"
#include "config.h"
#include "engine_vulkan.h"
#include "glfw/glfw3.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
printf("VLK Engine - Version %s\n", VERSION_NUMBER);
if (enable_validation_layers) {
printf("Validation layers enabled.\n");
}
printf("\n");
struct VulkanData vulkan_data = {0};
struct Application app = {.window = NULL, .vulkan_data = &vulkan_data, .objects = NULL};
bool ret = application_init(&app);
if (ret == false) {
fprintf(stderr, "Cannot initialize applcation.\n");
return EXIT_FAILURE;
}
while (application_loopcondition(&app)) {
application_loopevent(&app);
}
application_close(&app);
return EXIT_SUCCESS;
}
application.c
#include "application.h"
#include "engine_object.h"
#include "engine_vulkan.h"
bool application_init(struct Application *app) {
bool ret;
// Initialize GLFW
glfwInit();
// Create window
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
app->window = glfwCreateWindow(800, 600, "Vulkan window", NULL, NULL);
if (app->window == NULL) {
fprintf(stderr, "Failed to create window.\n");
return false;
}
printf("Created window # 0x%p\n", app->window);
// Initialize game object list
objectlink_init(app);
// Create game objects
struct RenderObjectCreateInfo ro_create_info = {.vertex_shader_path = "shaders/shader.vert.spv",
.fragment_shader_path =
"shaders/shader.frag.spv",
.is_static = true};
struct RenderObject triangle = {0};
object_init(app, &ro_create_info, &triangle);
objectlink_add(app, &triangle);
// Init Vulkan
ret = vulkan_init(app);
if (!ret) {
fprintf(stderr, "Failed to initialize Vulkan.\n");
return false;
}
return true;
}
bool application_loopcondition(struct Application *app) {
// Close only if GLFW says so
return !glfwWindowShouldClose(app->window);
}
void application_loopevent(struct Application *app) {
// Poll for events like keyboard & mouse
glfwPollEvents();
}
void application_close(struct Application *app) {
// Destroy objects
objectlink_destroy(app);
// Close Vulkan instance
vulkan_close(app);
// End window & GLFW
glfwDestroyWindow(app->window);
glfwTerminate();
}
Important structures
struct Application {
GLFWwindow *window;
struct VulkanData *vulkan_data;
struct RenderObjectLink *objects;
};
struct RenderObject {
char *vertex_shader_path;
struct ShaderFile vertex_shader_data;
VkShaderModule vertex_shader;
char *fragment_shader_path;
struct ShaderFile fragment_shader_data;
VkShaderModule fragment_shader;
bool is_static;
};
struct RenderObjectCreateInfo {
char *vertex_shader_path;
char *fragment_shader_path;
bool is_static;
};
struct RenderObjectLink {
struct RenderObject *render_object;
struct RenderObjectLink *next;
};
The problem in my application comes when storing the VkShaderModules in my application structure. The way that my program is supposed to store information about objects is in the Application structure called app, in which it points to a linked list of RenderObjectLink in the objects field. My functions objectlink_init and objectlink_add work properly, however the data inside the structure the render_object field points to gets changed/corrupted when entering the GLFW functions glfwWindowShouldClose and glfwPollEvents.
Since those two functions are ran after initializing Vulkan and creating the shader modules, I've found with GDB that the Vulkan functions are working properly and that my data structures are only getting corrupted when running the GLFW loop functions. I have debugged with GDB using hardware watch points to determine that the reference to these shaders (among other variables throughout the program) changes upon entering these functions.
Thread 1 hit Hardware watchpoint 4: app->objects->render_object->vertex_shader
Old value = (VkShaderModule) 0x731f0f000000000a
New value = (VkShaderModule) 0x40d625 <glfwPollEvents+43>
_glfwPlatformPollEvents () at C:/Users/dylanweber/Documents/C-Projects/vlkengine/main/glfw/src/win32_window.c:1878
1878 {
This happens consistently but the variable changes to different values when I run it. Memory analysis tools like Dr. Memory (since I'm using Windows I cannot use Valgrind) only show memory problems in system DLLs (like xinput reading for controller inputs through GLFW) and are unrelated to my program. What could be the cause of this corruption? What tools/resources can I use to find these issues?
According to the code, the objectlink_add function accepts the second argument as a pointer. The most likely use of this is to add the pointer to an underlying data struct and keep it around for further references. A render pipeline was mentioned in the post, which wold be a sort of link.
However, the function was called from the application_init procedure which has the object triangle allocated on its stack. By the time the function is returned, its stack is gone and the value at the pointer becomes invalid.
There are several ways to fix it:
To allocate the triangle struct dynamically, using malloc (or similar). Therefore it will no disappear after the return from the function. This is the most generic way, but it calling to the free() function at some time is expected.
The triangle object could be static.
the objectlink_add could copy triangle fields in some internal struct, however, if there are multiple types of the objects, it cold be problematic.

C Read from File into LinkedList

I have a text file that I need to read a populate a linked list. The file structure is like this.
Ant,Adam 10 5
Mander,Sally 4 3
King,May 6 6
King,Joe 9 6
Graph,Otto 2 5
Carr,Redd 1 3
The name is szName. The second int is iDepartTmUnits, and the last int is iTime;
I'm trying to read the input from stdin
It should insert EVT_ARRIVE and EVT_DEPART events into the simulation's eventList. Assuming you are using fgets and sscanf, please make certain you check the count returned from your sscanf.
// Event Constants
#define EVT_ARRIVE 1 // when a person arrives
#define EVT_DEPART 2 // when a person departs the simulation
We have these structures
typedef struct
{
char szName[16]; // Name
int iDepartTmUnits; // time units representing how long he/she stays around
} Person;
// Event typedef (aka Element)
typedef struct
{
int iEventType; // The type of event as an integer:
// EVT_ARRIVE - arrival event
// EVT_DEPART - departure event
int iTime; // The time the event will occur
Person person; // The person invokved in the event.
} Event;
// NodeLL typedef - these are the nodes in the linked list
typedef struct NodeLL
{
Event event;
struct NodeLL *pNext; // points to next node in the list
} NodeLL;
// typedefs for the ordered link list
typedef struct
{
NodeLL *pHead; // Points to the first node in the ordered list
} LinkedListImp;
typedef LinkedListImp *LinkedList;
// typedefs for the Simulation
typedef struct
{
int iClock; // clock time
LinkedList eventList; // A linked list of timed events
} SimulationImp;
typedef SimulationImp *Simulation;
Now where I am struggling is how to populate a linked list with this information.
Actually I'm struggling with a lot to grasp my head around this, so I'm sorry at the question being overly complex or overly simple.
First Thing I am struggling with
I'm declaring it as
void generateArival(Event eventM[])
I believe that is incorrect, because in my main, I wouldn't pass it the event, I believe I would pass it a Simulation implementation.
Second Thing I Am struggling with
Here is the code I have so far where I am too copy from the file into a linked list.
while(!feof(pFilePerson))
{
iLineCount++;
i++;
fgets(szInputBuffer, MAX_LINE_SIZE, pFilePerson);
iScanfCnt = sscanf(szInputBuffer,"%s %d %d\n",
event.person.szName,
event.iTime,
event.person.iDepartTmUnits,
);
}
Lastly
I am to input the EVT_ARRIVE and EVT_DEPART into the eventList.
I believe that to be something like this,
they are int 1 and 2 respectfully, so I would need something like iEvent = event.iEventType;
and input that into the sim->eventList
Any help is appreciated, I need a lot more time with this concept of linked lists, but this is breaking my head.
EDIT
I can print out the name but not the numbers
while(fgets(szInputBuffer, sizeof szInputBuffer, pFilePerson) != NULL)
{
// print the input buffer as is (it also has a linefeed)
//printf("Person # %d: %s\n", iLineCount, szInputBuffer);
sscanf(szInputBuffer,"%s",
event.person.szName);
sscanf(szInputBuffer, "%I64d",
&event.person.iDepartTmUnits);
//linkList.event.iTime);
printf("%-7s\n", event.person.szName);
printf("%d\n", event.person.iDepartTmUnits);
}

(C Programming) How do I use a data structure and function which are defined in another file?

Say, I have a file dataStructure.c and dataStructure.h. (My data structure is a hash map.) These files contain the implementation of the data structure and methods for adding new entries to the structure as well as retrieving entries.
Here's an example:
// dataStructure.h
struct node {
char *label;
int address;
struct node *next; // Points to the next node.
};
struct ourTable {
int size;
struct node **list; // List of all the (key, value) pairs.
};
// Then, here are methods to create table, add new entries and retrieving them.
struct ourTable createTable(int size);
void addEntry(struct ourTable *t, char *label, int address);
unsigned retrieveAddress(struct ourTable* table, char *label);
The function retrieveAddress basically just returns the address of that label. Since I am trying to implement a hash map, which is just a data structure of several (key, value) pairs. In my case, the key is label whereas value is address.
unsigned retrieveAddress( struct ourTable* table, char *label)
{
int bin = 0;
bin = hashFunction(table, label); // Hashing function
struct node *list = table->list[bin];
struct node *entryItem = list;
while(entryItem)
{
if (entryItem->label == label)
{
return entryItem->address; // Returns the address of that label.
}
entryItem = entryItem->next;
}
return NULL;
}
Then, I have another file, establishTable.c which just uses the methods implemented in dataStructure.h to create a table and then add new entries. This is what I wrote in that file:
// establishTable.c
#include "dataStructure.h"
struct ourTable establishTable()
{
struct ourTable table = createTable(1000); // Create a table with a maximum of 1000 entries.
addEntry(&table, "word", 1234);
}
And what I want to do is to pass the structure ourTable with the new entries I inserted in establishTable.c to the main file main.c. To illustrate what I am trying to accomplish:
// main.c
#include "dataStructure.h"
#include "establishTable.h"
int main()
{
// I'm not sure how to pass the data structure... Something like this:
struct ourTable table = establishTable();
// Get the retrieveLabel function from dataStructure.h and use it here.
printf("retrieved from the table at %u\n\n", retrieveAddress(&table,"word") );
}
I tried running the main.c. It doesn't show any errors but it just outputs
retrieved from the table at 0
which just tells me that the table I already established was not passed on at all. The output should be 1234.
So, how do I pass a data structure and the result of a function from another file to my main.c file? It works when I just do everything in establishTable.c but that is not my intention. I have tried the extern method as suggested in other threads, but nothing works.
You forgot the return statement
struct ourTable establishTable()
{
struct ourTable table = createTable(1000); // Create a table with a maximum of 1000 entries.
addEntry(&table, "word", 1234);
return table;
}

How to navigate around a linked list?

So let's say I have 3 nodes in my linked lists, each with a first name in it. The list is supposed to be ordered alphabetically. I need to navigate with pointers
I have a .h interface and a .c file implementation, so you can assume anything prototyped int he List.c file is not in the header file.
Let me explain what's going on logically, to make my code a bit easier to understand. ListP is a pointer to struct List that has simple attributes like logical size, physical size and a pointer to the head of the linked list. The character strings are typedefd as ListItemP for easy reconstruction to an integer linked list etc if need be.
List.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "List.h"
typedef struct Entry *EntryP;
EntryP newEntry(ListItemP thisItem);
struct List
{
int sizeL;
int sizeP;
ListItemP head;
};
struct Entry
{
ListItemP content;
struct Entry *next;
};
ListP newList()
{
ListP thisList = (ListP) malloc(sizeof(ListP));
thisList->head = 0x00;
thisList->sizeL = 0;
thisList->sizeP = 0;
return thisList;
}
void insertItemList(ListP thisList, ListItemP thisItem)
{
EntryP thisEntry = newEntry(thisItem);
thisEntry->content = thisItem;
// Make a conditional for the first condition (no items in list)
if ((thisList->head == 0x00) || (strcmp(thisItem, thisList->head) < 0)) {
thisList->head = thisEntry->content;
thisEntry->next = 0x00;
}
// The other conditional are what I don't understand, how to put go through
navigate through the list via pointers and such.
thisList->sizeL++;
thisList->sizeP++;
}
void displayList(ListP thisList)
{
printf("First Item: %s\n",thisList->head);
}
/*
* Not in the interface
*/
EntryP newEntry(ListItemP thisItem)
{
EntryP thisEntry = (EntryP) malloc(sizeof(EntryP));
thisEntry->content = thisItem;
thisEntry->next = NULL;
return thisEntry;
}
I would post my main.c (or tester.c or whatever you want to call it) but I don't really think its going to help at all, all the linked list navigation is going to occur in the List.c file.
So my question is this, assuming I have 3 or 4 or however many nodes, how can I navigate around them so I can do things like string compares and yadda yadda in order to place new strings in the linked list in alphabetical order.
Thank you!

Binary Tree of Strings returning wrong order

I am fairly new to C and have been learning from K&R's book The C Programming Language.
After doing the exercises on Binary trees I wanted to make a header for binary trees for
char*, long and double.
There is a function in the following code that has been giving me grief - it should fill an array of character pointers with the values stored in the tree in lexicographical order however it has a bug somewhere. Here's the code for the String Tree Header btree.h:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/************** TYPES **************/
typedef struct ctree
{
char *name;
ctree *left;
ctree *right;
};
/************** Globals **************/
static int c_inc = 0;
/************** Function Prototypes **************/
ctree *add_to_c_tree (ctree *cnode, char *name);
void print_c_tree (ctree *cnode);
ctree *c_tree_alloc (void);
void c_tree_free (ctree *cnode);
void return_c_tree (ctree *cnode, char **array);
/************** Function Definitions **************/
/* add_to_c_tree() : Adds a new node to a *character binary tree */
ctree *add_to_c_tree (ctree *cnode, char *name){
/* If the node is null, allocate memory for it,
* copy the name and set the internal nodes to null*/
if(cnode == NULL){
cnode = c_tree_alloc();
cnode->name = strdup(name);
cnode->left = cnode->right = NULL;
}
/* If initialised then add to the left node if it is lexographically
* less that the node above it else add it to the right node */
else{
if(strcmp(name, cnode->name) < 0)
cnode->left = add_to_c_tree(cnode->left,name);
else if(strcmp(name, cnode->name) > 0)
cnode->right = add_to_c_tree(cnode->right,name);
}
return cnode;
}
/* print_c_tree() : Print out binary tree */
void print_c_tree(ctree *cnode){
if (cnode != NULL) {
print_c_tree(cnode->left);
printf("%s\n",cnode->name);
print_c_tree(cnode->right);
}
}
/* return_c_tree() : return array of strings containing all values in binary tree */
void return_c_tree (ctree *cnode, char **array){
if (cnode != NULL) {
return_c_tree (cnode->left,array+c_inc);
c_tree_free(cnode->left);
*(array+c_inc++) = strdup(cnode->name);
// printf("arr+%d:%s\n", c_inc-1,*(array+(c_inc-1)));
return_c_tree (cnode->right,array+c_inc);
c_tree_free(cnode->right);
}
}
/* c_tree_alloc() : Allocates space for a tree node */
ctree *c_tree_alloc(void){
return (ctree *) malloc(sizeof(ctree));
}
/* c_tree_free() : Free's Memory */
void c_tree_free (ctree *cnode){
free(cnode);
}
Which I have been testing with bt.c:
#include "btree.h"
int main(void){
ctree *node = NULL; char *arr[100];
node = add_to_c_tree(node, "foo");
node = add_to_c_tree(node, "yoo");
node = add_to_c_tree(node, "doo");
node = add_to_c_tree(node, "woo");
node = add_to_c_tree(node, "aoo");
node = add_to_c_tree(node, "boo");
node = add_to_c_tree(node, "coo");
print_c_tree(node);
return_c_tree(node,arr);
for (int i = 0; i < 7; ++i)
{
printf("%d:%s ..\n",i, arr[i]);
}
return 0;
}
The reason for this question is that I have been having issues with the return_c_tree() function, which is meant to mimic the behaviour of K&R's print_c_tree() function except instead of recursively calling itself until a NULL ptr and printing out the name of the nodes in lexicographical order it is meant to add their names to an array of character ptrs and free the nodes memory.
However the output I get when run as above is:
aoo
boo
coo
doo
foo
woo
yoo
0:aoo ..
1:(null) ..
2:boo ..
3:doo ..
4:foo ..
5:coo ..
6:(null) ..
Which shows that the print function works fine but the return function obviously isn't.
The confusing thing is that if the call to printf() in return_c_tree() is uncommented this is the result:
aoo
boo
coo
doo
foo
woo
yoo
arr+0:aoo
arr+1:boo
arr+2:coo
arr+3:doo
arr+4:foo
arr+5:woo
arr+6:yoo
0:aoo ..
1:(null) ..
2:boo ..
3:doo ..
4:foo ..
5:coo ..
6:(null) ..
Which implies that it actually does add the strings in the right order.
Also I have tried it without the c_inc variable -> ie just incrementing array
before passing it to the right node which the produces the same results from the printf
in return_c_tree() but different from main:
arr+-1:aoo
arr+-1:boo
arr+-1:coo
arr+-1:doo
arr+-1:foo
arr+-1:woo
arr+-1:yoo
0:foo ..
1:yoo ..
2:coo ..
3:(null) ..
4:(null) ..
5:(null) ..
6:(null) ..
I'm rather confused, so If anyone can help I would appreciate it greatly. I'm sure I'm just incrementing it in the wrong place but I can't work out where.
I thought I had finally understood pointers but apparently not.
Best
P
Your problem is how you handle your pointer to array when you recursively call. This will fix your return_c_tree function:
void return_c_tree (ctree *cnode, char **array)
{
if (cnode != NULL) {
return_c_tree (cnode->left,array); // <--- CHANGED 2ND PARAM
c_tree_free(cnode->left);
*(array+c_inc++) = strdup(cnode->name);
return_c_tree (cnode->right,array); // <--- AGAIN, CHANGED 2ND PARAM
c_tree_free(cnode->right);
}
}
You're using a global variable c_inc to keep track of the current index into the array. However, when you recursively called return_c_tree, you passed in array+c_inc, but you did not offset c_inc to account for this. Basically, you double-counted c_inc each time.
While this solves your particular problem, there are some other problems with your code.
In general, using global variables is asking for trouble. There's no need to do it here. Pass c_inc as a parameter to return_c_tree.
Also, mixing global variables with recursion is especially prone to problems. You really want recursive routines to keep their state on the stack.
As a commenter pointed out, all of your code in btree.h should really be in btree.c. The point of header files is to define an interface, not for code.
(This is more stylistic) Your return_c_tree function is really two distinct functions: copy the elements of the tree (in order) into the array, and free the memory used by the tree. These two operations are conceptually distinct: there are times that you'll want to do one and not both. There can be compelling performance (or other) reasons to mix the two, but wait until you have some hard evidence.

Resources