My problem is that this code is not working in VS 2017 while in CLion it works.
VS says:
Severity Code Description Project File Line Suppression State
Error (active) E0144
a value of type void * cannot be used to initialize an entity of type queue_t*
therefor the program is not allocating the memory.
Further every pointer like the example above is not working.
Does somebody here know why that is the case, why VS thinks that this would be a void?
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
struct packet_t {
double d;
int i;
long l;
char *p;
struct queue_t *queue;
};
struct queue_t {
char *name;
int size;
int entries;
double time;
struct packet_t **packets;
int read;
int write;
long lost;
long total;
};
int decision = -1;
int isRunning = 1;
void logError(char message[]) {
printf("ERROR: %s", message);
}
struct queue_t *queue_create(char *name, int size) {
struct queue_t *q = malloc(sizeof(struct queue_t));
if (!q) {
logError("could not allocate memory!\n");
return 0;
}
else {
q->name = name;
q->size = size;
q->entries = 0;
q->read = 0;
q->write = 0;
q->total = 0;
q->lost = 0;
q->packets = malloc(size * sizeof(struct packet_t *));
if (!q->packets) {
logError("could not allocate memory!\n");
free(q);
return 0;
}
struct packet_t **current;
for (int i = 0; i < size; i++) {
current = q->packets + i;
*current = NULL;
}
}
return q;
}
int packet_destroy(struct packet_t *packet) {
//TODO test if deleted ?
if (packet) {
free(packet);
return 1;
}
return 0;
}
long queue_store(struct queue_t *queue, struct packet_t *packet) {
if (queue->entries < queue->size) {
packet->queue = queue;
*(queue->packets + queue->write) = packet;
queue->write++;
if (queue->write == queue->size) {
queue->write = 0;
}
queue->total++;
queue->entries++;
return queue->total;
}
//cant save packet ->destroy
packet_destroy(packet);
queue->lost++;
return 0;
}
struct packet_t *queue_retrieve(struct queue_t *queue) {
if (queue->entries == 0) return NULL;
struct packet_t **current = queue->packets + queue->read;
struct packet_t *packet = *current;
*current = NULL;
if (packet->queue) {
packet->queue = NULL;
}
queue->entries--;
queue->read++;
if (queue->read == queue->size) {
queue->read = 0;
}
return packet;
}
struct packet_t *packet_create(int i, double d, long l, char *p) {
struct packet_t *new = malloc(sizeof(struct packet_t));
if (new) {
new->i = i;
new->d = d;
new->l = l;
new->p = p;
}
else {
logError("failed to allocate memory");
}
return new;
}
int queue_destroy(struct queue_t *queue) {
if (!queue) {
logError("could not find queue!");
return 0;
}
struct packet_t *p;
for (int i = 0; i < queue->size; i++) {
p = *(queue->packets + i);
packet_destroy(p);
}
//TODO test if not needed as it's already free'd in packet_destroy
free(queue->packets);
free(queue);
return 0;
}
long test_queue(int val) {
int sum = 0, finalTime = 0;
clock_t startTime, finalTicks;
startTime = clock();
while (finalTime < val) {
struct queue_t *q = queue_create("test", 10);
queue_destroy(
sum++;
finalTicks = (clock() - startTime);
// printf("ticks: %d\n", finalTicks);
finalTime = (int)floor((finalTicks / (double)CLOCKS_PER_SEC));
// printf("time: %d\n", finalTime);
}
printf("Runtime: %d\n seconds", finalTime);
printf("Added and removed %d queues\n", sum);
}
long test_packets(int val) {
int finalTime = 0;
struct queue_t *q = queue_create("test", 10);
clock_t startTime, finalTicks;
startTime = clock();
while (finalTime < val) {
struct packet_t *t = packet_create(finalTime, finalTime + 1, finalTime + 2, NULL);
queue_store(q, t);
packet_destroy(queue_retrieve(q));
finalTicks = (clock() - startTime);
// printf("ticks: %d\n", finalTicks);
finalTime = (int)floor((finalTicks / (double)CLOCKS_PER_SEC));
// printf("time: %d\n", finalTime);
}
printf("Runtime: %d\n", finalTime);
printf("Successfully added %li entries\n", q->total);
printf("Failed to add %li entries\n", q->lost);
queue_destroy(q);
}
void resetDecision() {
decision = -1;
isRunning = 1;
}
void checkDecision() {
while (decision != 0 && decision != 1 && decision != 2) {
printf("Select option:\n (1) Run queue test \n (2) Run packet test \n(0) to cancel \n");
scanf("%d", &decision);
}
if (decision == 0) {
isRunning = 0;
}
else if (decision == 1) {
int val = 0;
while (val <= 0) {
printf("Enter the time to test");
scanf("%d", &val);
}
printf("Running test for %d seconds....\n", val);
test_queue(val);
}
else if (decision == 2) {
int val = 0;
while (val <= 0) {
printf("Enter the time to test");
scanf("%d", &val);
}
printf("Running test for %d seconds....\n", val);
test_packets(val);
}
if (decision != 0)
resetDecision();
}
int main() {
while (isRunning) {
checkDecision();
}
return 0;
}
You are compiling your program as a C++ program. In C++ there is no implicit conversion from the type void * to pointer of other object type.
So you need to write using explicit casting like
struct queue_t *q = ( struct queue_t * )malloc(sizeof(struct queue_t));
Or you should consider your program as indeed a C++ program and use the operator new instead of the C function malloc.
Related
I am trying to build an efficient concurrent hash map using pthreads, C.
Following is my implementation
#include <stdlib.h>
#include <stddef.h>
#include <pthread.h>
#include <stdint.h>
#include <limits.h>
#include <stdio.h>
#include <linux/limits.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#define ENTRIES_PER_BUCKET 3
struct Bucket
{
pthread_mutex_t mutex;
void **keys;
int *vals;
struct Bucket *next;
};
struct Concurrent_Map
{
struct Bucket *buckets;
map_keys_equality *keys_eq;
map_key_hash *khash;
int capacity;
};
int concurrent_map_allocate /*# <t> #*/ (map_keys_equality *keq, map_key_hash *khash,
unsigned capacity,
struct Concurrent_Map **map_out)
{
struct Concurrent_Map *old_map_val = *map_out;
struct Concurrent_Map *map_alloc = malloc(sizeof(struct Concurrent_Map));
if (map_alloc == NULL)
{
return 0;
}
*map_out = (struct Concurrent_Map *)map_alloc;
struct Bucket *buckets_alloc = (struct Bucket *)malloc(sizeof(struct Bucket) * (int)capacity);
if (buckets_alloc == NULL)
{
free(map_alloc);
*map_out = old_map_val;
return 0;
}
(*map_out)->buckets = buckets_alloc;
(*map_out)->capacity = capacity;
(*map_out)->keys_eq = keq;
(*map_out)->khash = khash;
unsigned i;
for (i = 0; i < capacity; i++)
{
if (pthread_mutex_init(&((*map_out)->buckets[i].mutex), NULL) == 0)
{
void **key_alloc = malloc(sizeof(void *) * (ENTRIES_PER_BUCKET));
if (key_alloc != NULL)
{
(*map_out)->buckets[i].keys = key_alloc;
int k;
for (k = 0; k < ENTRIES_PER_BUCKET; k++)
{
(*map_out)->buckets[i].keys[k] = NULL;
}
}
int *vals_alloc = malloc(sizeof(int) * (ENTRIES_PER_BUCKET));
if (vals_alloc != NULL)
{
(*map_out)->buckets[i].vals = vals_alloc;
int k;
for (k = 0; k < ENTRIES_PER_BUCKET; k++)
{
(*map_out)->buckets[i].vals[k] = -1;
}
}
(*map_out)->buckets[i].next = NULL;
}
}
// todo exceptions in allocation
return 1;
}
static unsigned loop(unsigned k, unsigned capacity)
{
unsigned g = k % capacity;
unsigned res = (g + capacity) % capacity;
return res;
}
int concurrent_map_get(struct Concurrent_Map *map, void *key, int *value_out)
{
map_key_hash *khash = map->khash;
unsigned hash = khash(key);
unsigned start = loop(hash, map->capacity);
unsigned bucket_index = loop(start + 0, map->capacity);
if (bucket_index < map->capacity)
{
struct Bucket *bucket = &(map->buckets[bucket_index]);
pthread_mutex_t mutex = bucket->mutex;
pthread_mutex_lock(&mutex);
int j;
do
{
for (j = 0; j < ENTRIES_PER_BUCKET; j++)
{
int val = bucket->vals[j];
if (map->keys_eq(bucket->keys[j], key))
{
if (bucket->vals[j] == val)
{
*value_out = val;
return 1;
}
else
{
*value_out = -1;
return 0;
}
}
}
if (bucket->next != NULL)
{
bucket = (bucket->next);
}
else
{
break;
pthread_mutex_unlock(&mutex);
}
pthread_mutex_unlock(&mutex);
} while (1);
}
*value_out = -1;
return 0;
}
int concurrent_map_put(struct Concurrent_Map *map, void *key, int value)
{
map_key_hash *khash = map->khash;
unsigned hash = khash(key);
unsigned start = loop(hash, map->capacity);
unsigned bucket_index = loop(start + 0, map->capacity);
struct Bucket *bucket = &(map->buckets[bucket_index]);
int j;
do
{
pthread_mutex_t mutex = bucket->mutex;
int j;
pthread_mutex_lock(&mutex);
for (j = 0; j < ENTRIES_PER_BUCKET; j++)
{
if (map->keys_eq(bucket->keys[j], key))
{
pthread_mutex_unlock(&mutex);
return 0;
}
else if (bucket->keys[j] == NULL)
{
bucket->vals[j] = value;
bucket->keys[j] = key;
pthread_mutex_unlock(&mutex);
return 1;
}
}
if (bucket->next == NULL)
{
// allocate a new bucket
struct Bucket *new_bucket = malloc(sizeof(struct Bucket));
if (pthread_mutex_init(&(new_bucket->mutex), NULL) == 0)
{
void **key_alloc = malloc(sizeof(void *) * (ENTRIES_PER_BUCKET));
if (key_alloc != NULL)
{
new_bucket->keys = key_alloc;
int k;
for (k = 0; k < ENTRIES_PER_BUCKET; k++)
{
new_bucket->keys[k] = NULL;
}
}
int *vals_alloc = malloc(sizeof(int) * (ENTRIES_PER_BUCKET));
if (vals_alloc != NULL)
{
new_bucket->vals = vals_alloc;
int k;
for (k = 0; k < ENTRIES_PER_BUCKET; k++)
{
new_bucket->vals[k] = -1;
}
}
bucket->next = new_bucket;
}
}
pthread_mutex_unlock(&mutex);
bucket = bucket->next;
} while (1);
return 0;
}
int concurrent_map_erase(struct Concurrent_Map *map, void *key, void **trash)
{
map_key_hash *khash = map->khash;
unsigned hash = khash(key);
unsigned start = loop(hash, map->capacity);
unsigned bucket_index = loop(start + 0, map->capacity);
struct Bucket *bucket = &(map->buckets[bucket_index]);
int j;
do
{
pthread_mutex_t mutex = bucket->mutex;
int j;
pthread_mutex_lock(&mutex);
for (j = 0; j < ENTRIES_PER_BUCKET; j++)
{
if (map->keys_eq(bucket->keys[j], key))
{
bucket->vals[j] = -1;
bucket->keys[j] = NULL;
pthread_mutex_unlock(&mutex);
return 1;
}
}
pthread_mutex_unlock(&mutex);
if (bucket->next != NULL)
{
bucket = (bucket->next);
}
else
{
break;
}
} while (1);
return 0;
}
int concurrent_map_size(struct Concurrent_Map *map)
{
int num_buckets = 0;
struct Bucket *buckets = map->buckets;
unsigned i;
for (i = 0; i < map->capacity; i++)
{
struct Bucket bucket = buckets[i];
do
{
num_buckets++;
if (bucket.next != NULL)
{
bucket = *(bucket.next);
}
else
{
break;
}
} while (1);
}
return num_buckets * ENTRIES_PER_BUCKET;
}
struct FlowId
{
int src_port;
int dst_port;
int src_ip;
int dst_ip;
int internal_device;
int protocol;
};
bool FlowId_eq(void *a, void *b)
{
if (a == NULL || b == NULL)
{
return false;
}
struct FlowId *id1 = a;
struct FlowId *id2 = b;
return (id1->src_port == id2->src_port) && (id1->dst_port == id2->dst_port) && (id1->src_ip == id2->src_ip) && (id1->dst_ip == id2->dst_ip) && (id1->internal_device == id2->internal_device) && (id1->protocol == id2->protocol);
}
unsigned FlowId_hash(void *obj)
{
struct FlowId *id = obj;
unsigned hash = 0;
hash = __builtin_ia32_crc32si(hash, id->src_port);
hash = __builtin_ia32_crc32si(hash, id->dst_port);
hash = __builtin_ia32_crc32si(hash, id->src_ip);
hash = __builtin_ia32_crc32si(hash, id->dst_ip);
hash = __builtin_ia32_crc32si(hash, id->internal_device);
hash = __builtin_ia32_crc32si(hash, id->protocol);
return hash;
}
struct Concurrent_Map *concurrent_map;
#define NUM_THREADS 2
#define NUM_PACKETS 10000000
void *expirator(void *arg)
{
// printf("Thread started executing\n");
unsigned i = 0;
int error = 0;
unsigned packet_count = NUM_PACKETS / NUM_THREADS;
while (i < packet_count)
{
i++;
struct FlowId *id = malloc(sizeof(struct FlowId));
struct FlowId *id1 = malloc(sizeof(struct FlowId));
id->dst_ip = 1;
id->src_ip = 1;
id->internal_device = 1;
id->protocol = 1;
id->src_port = 1;
id->dst_port = rand() % 65536;
id1->dst_ip = 1;
id1->src_ip = 1;
id1->internal_device = 1;
id1->protocol = 1;
id1->src_port = 1;
id1->dst_port = rand() % 65536;
int external_port = rand() % 65536;
int external;
concurrent_map_erase(concurrent_map, id, NULL);
concurrent_map_put(concurrent_map, id, external_port);
concurrent_map_get(concurrent_map, id, &external);
if (external_port != external)
{
error++;
}
else
{
}
}
return NULL;
}
int main()
{
clock_t begin = clock();
concurrent_map_allocate(FlowId_eq, FlowId_hash, 65536, &(concurrent_map));
pthread_t *threads = malloc(sizeof(pthread_t) * NUM_THREADS);
int i;
for (i = 0; i < NUM_THREADS; i++)
{
if (pthread_create(&threads[i], NULL, expirator, NULL) != 0)
{
printf("Error creating threads");
exit(0);
}
}
for (i = 0; i < NUM_THREADS; i++)
{
if (pthread_join(threads[i], NULL) != 0)
{
printf("Error joining threads");
exit(0);
}
}
clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("%lf\n", time_spent);
return 0;
}
Here is how to run this program.
gcc concurrent_map.c -o test-concurrent-new -lpthread -msse4.2 -O3
Then I measure the execution time for a fixed workload and following are the time values I observed.
1: 3.29
2: 6.687811
3: 5.88
4: 6.23
5: 6.38
6: 6.52
7: 6.74
8: 6.82
It seems that when the number of threads is increased the execution time increases and remains almost same.
I profiled this code using Mutrace, which looks for mutex contention. It turns out that
No mutex contended according to filtering parameters.
I checked the number of cache misses, and it turned out that number of cache misses are roughly equal when the number of threads is modified.
Why does not the execution time decrease when the number of threads increase?
I am running this on a 32 core machine
rand() is usually not suited for multi threaded execution. Instead use rand_r().
Also use linux time tool for timing the application.
Your workload generation imposes a huge overhead, and I assume it is the bottleneck here, not the concurrent hash map
This following code must be able of add to ArrayList each process name since that current name still not is stored on list. The code of ArrayList implementation was from this reference, but have a trouble that, when changed int to UNICODE_STRING data (in Element structure, cause a sintaxe error on line:
if (e.data == list->elements[index].data) return index;
Error 1 error C2088: '==' : illegal for struct
of indexOf() routine.
So, how fix?
Code:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include <Winternl.h>
#pragma comment(lib,"ntdll.lib")
typedef struct _SYSTEM_PROCESS_INFO
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
ULONG BasePriority;
HANDLE ProcessId;
HANDLE InheritedFromProcessId;
}SYSTEM_PROCESS_INFO, *PSYSTEM_PROCESS_INFO;
typedef struct
{
UNICODE_STRING data;
}Element;
typedef struct
{
int current;
int size;
int increment_rate;
Element *elements;
}ArrayList;
void initWithSizeAndIncRate(ArrayList *const list, int size, int rate)
{
list->size = size;
list->increment_rate = rate;
list->elements = (Element*)calloc(sizeof(Element), list->size);
list->current = -1;
}
void initWithSize(ArrayList *const list, int size)
{
initWithSizeAndIncRate(list, size, 50);
}
void init(ArrayList *const list)
{
initWithSize(list, 100);
}
void arraryCopy(void *dest, int dIndex, const void* src, int sIndex, int len, int destLen, size_t size)
{
uint8_t *udest = (uint8_t*)dest;
uint8_t *usrc = (uint8_t*)src;
dIndex *= size;
sIndex *= size;
len *= size;
destLen *= size;
if (src != dest)
{
memcpy(&udest[dIndex], &usrc[sIndex], len);
}
else
{
if (dIndex > sIndex)
{
uint8_t *tmp = (uint8_t*)calloc(destLen, size);
memcpy(tmp, &udest[dIndex], (destLen - dIndex));
memcpy(&udest[dIndex], &usrc[sIndex], len);
memcpy(&udest[dIndex + len], tmp, (destLen - dIndex));
free(tmp);
}
else if (sIndex > dIndex)
{
memcpy(&udest[dIndex], &usrc[sIndex], (destLen - sIndex) + 1);
}
else
return;
}
}
void clear(ArrayList *const list)
{
while (list->current >= 0)
{
list->elements[list->current] = (Element){ 0 };
list->current--;
}
}
void wide(ArrayList* const list)
{
list->size += list->increment_rate;
Element *newArr = (Element*)calloc(sizeof(Element), list->size);
arraryCopy(newArr, 0, list->elements, 0, list->current, list->size, sizeof(Element));
free(list->elements);
list->elements = newArr;
}
int add(ArrayList *const list, Element e)
{
if (++list->current < list->size)
{
list->elements[list->current] = e;
return 1;
}
else
{
wide(list);
list->elements[list->current] = e;
return 1;
}
return 0;
}
int indexOf(const ArrayList *const list, Element e)
{
int index = 0;
while (index <= list->current)
{
if (e.data == list->elements[index].data) return index;
index++;
}
return 0;
}
void printElement(const Element *const e)
{
printf("%i ", e->data);
}
void print(const ArrayList *const list)
{
int i;
for (i = 0; i <= list->current; i++)
{
Element e = list->elements[i];
printElement(&e);
}
printf("\n");
}
void clean(ArrayList *list)
{
free(list->elements);
}
int _tmain(int argc, _TCHAR* argv[])
{
NTSTATUS status;
PVOID buffer;
PSYSTEM_PROCESS_INFO spi;
ArrayList list;
init(&list);
buffer = VirtualAlloc(NULL, 1024 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!buffer)
{
printf("\nError: Unable to allocate memory for process list (%d)\n", GetLastError());
return -1;
}
printf("\nProcess list allocated at address %#x\n", buffer);
spi = (PSYSTEM_PROCESS_INFO)buffer;
if (!NT_SUCCESS(status = NtQuerySystemInformation(SystemProcessInformation, spi, 1024 * 1024, NULL)))
{
printf("\nError: Unable to query process list (%#x)\n", status);
VirtualFree(buffer, 0, MEM_RELEASE);
return -1;
}
while (spi->NextEntryOffset)
{
printf("\nProcess name: %wZ | Process ID: %d\n", &spi->ImageName, spi->ProcessId);
int i = indexOf(&list, (Element){ spi->ImageName });
if (i > 0)
print("process already in list \n");
else
add(&list, (Element){ spi->ImageName });
spi = (PSYSTEM_PROCESS_INFO)((LPBYTE)spi + spi->NextEntryOffset);
}
VirtualFree(buffer, 0, MEM_RELEASE);
print(&list);
clean(&list);
_getch();
return 0;
}
EDIT:
After answer of #Johnny Mopp below, now how call correctly indexof routine?
I tried like this:
int i = indexOf(&list, (Element){ &spi->ImageName.Buffer });
if (i >= 0)
printf("process already in list \n");
else
add(&list, (Element){ &spi->ImageName.Buffer });
but indexof say that all already is present in list, this is wrong!
EDIT 2:
Error after first edition of answer:
IMAGE
UNICODE_STRING is a struct. You'll have to either do memcmp() on the entire struct or wcscmp() on e.data.Buffer
int indexOf(const ArrayList *const list, Element e)
{
int index = 0;
while (index <= list->current)
{
// Check same lengths and then do string compare
if (e.data.Length == list->elements[index].data.Length &&
0 == wcsncmp(e.data.Buffer,
list->elements[index].data.Buffer,
list->elements[index].data.Length))
return index;
index++;
}
return 0;
}
// Update after comment
Here's the whole thing with proper memory management of the UNICODE_STRINGs
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include <Winternl.h>
#pragma comment(lib,"ntdll.lib")
typedef struct _SYSTEM_PROCESS_INFO
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
ULONG BasePriority;
HANDLE ProcessId;
HANDLE InheritedFromProcessId;
}SYSTEM_PROCESS_INFO, *PSYSTEM_PROCESS_INFO;
typedef struct
{
// Changed to be a pointer
UNICODE_STRING *data;
}Element;
typedef struct
{
int current;
int size;
int increment_rate;
Element *elements;
}ArrayList;
// Duplicate a UNICODE_STRING
UNICODE_STRING * CopyUString(UNICODE_STRING *src)
{
UNICODE_STRING *dest = (UNICODE_STRING *) malloc(sizeof UNICODE_STRING);
dest->Length = src->Length;
dest->MaximumLength = src->MaximumLength;
dest->Buffer = (PWSTR) malloc(sizeof WCHAR * dest->MaximumLength);
memcpy(dest->Buffer, src->Buffer, sizeof WCHAR * dest->MaximumLength);
return dest;
}
// Free a duplicated UNICODE_STRING
void FreeUString(UNICODE_STRING *src)
{
free(src->Buffer);
free(src);
}
void initWithSizeAndIncRate(ArrayList *const list, int size, int rate)
{
list->size = size;
list->increment_rate = rate;
list->elements = (Element*) calloc(sizeof(Element), list->size);
list->current = -1;
}
void initWithSize(ArrayList *const list, int size)
{
initWithSizeAndIncRate(list, size, 50);
}
void init(ArrayList *const list)
{
initWithSize(list, 100);
}
void arraryCopy(void *dest, int dIndex, const void* src, int sIndex, int len, int destLen, size_t size)
{
uint8_t *udest = (uint8_t*) dest;
uint8_t *usrc = (uint8_t*) src;
dIndex *= size;
sIndex *= size;
len *= size;
destLen *= size;
if (src != dest)
{
memcpy(&udest[dIndex], &usrc[sIndex], len);
}
else
{
if (dIndex > sIndex)
{
uint8_t *tmp = (uint8_t*) calloc(destLen, size);
memcpy(tmp, &udest[dIndex], (destLen - dIndex));
memcpy(&udest[dIndex], &usrc[sIndex], len);
memcpy(&udest[dIndex + len], tmp, (destLen - dIndex));
free(tmp);
}
else if (sIndex > dIndex)
{
memcpy(&udest[dIndex], &usrc[sIndex], (destLen - sIndex) + 1);
}
else
return;
}
}
void clear(ArrayList *const list)
{
while (list->current >= 0)
{
FreeUString(list->elements[list->current].data);
list->current--;
}
}
void wide(ArrayList* const list)
{
list->size += list->increment_rate;
Element *newArr = (Element*) calloc(sizeof(Element), list->size);
arraryCopy(newArr, 0, list->elements, 0, list->current, list->size, sizeof(Element));
free(list->elements);
list->elements = newArr;
}
int add(ArrayList *const list, Element *e)
{
if (++list->current < list->size)
{
list->elements[list->current].data = CopyUString(e->data);
return 1;
}
else
{
wide(list);
list->elements[list->current].data = CopyUString(e->data);
return 1;
}
return 0;
}
int indexOf(const ArrayList *const list, Element *e)
{
int index = 0;
while (index <= list->current)
{
// Check same lengths and then do string compare
if (e->data->Length == list->elements[index].data->Length &&
0 == wcsncmp(e->data->Buffer,
list->elements[index].data->Buffer,
list->elements[index].data->Length))
return index;
index++;
}
return 0;
}
void printElement(const Element *const e)
{
wprintf(L"%s ", e->data->Buffer);
}
void print(const ArrayList *const list)
{
int i;
for (i = 0; i <= list->current; i++)
{
Element e = list->elements[i];
printElement(&e);
}
printf("\n");
}
void clean(ArrayList *list)
{
free(list->elements);
}
int _tmain(int argc, _TCHAR* argv [])
{
NTSTATUS status;
PVOID buffer;
PSYSTEM_PROCESS_INFO spi;
ArrayList list;
init(&list);
buffer = VirtualAlloc(NULL, 1024 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!buffer)
{
printf("\nError: Unable to allocate memory for process list (%d)\n", GetLastError());
return -1;
}
printf("\nProcess list allocated at address %#x\n", buffer);
spi = (PSYSTEM_PROCESS_INFO) buffer;
if (!NT_SUCCESS(status = NtQuerySystemInformation(SystemProcessInformation, spi, 1024 * 1024, NULL)))
{
printf("\nError: Unable to query process list (%#x)\n", status);
VirtualFree(buffer, 0, MEM_RELEASE);
return -1;
}
Element e;
while (spi->NextEntryOffset)
{
printf("\nProcess name: %wZ | Process ID: %d\n", &spi->ImageName, spi->ProcessId);
e.data = &(spi->ImageName);
int i = indexOf(&list, &e);
if (i > 0)
printf("process already in list \n");
else
add(&list, &e);
spi = (PSYSTEM_PROCESS_INFO) ((LPBYTE) spi + spi->NextEntryOffset);
}
VirtualFree(buffer, 0, MEM_RELEASE);
print(&list);
clean(&list);
_getch();
return 0;
}
I do not know why this is not working.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// struct of list
typedef struct noeud
{
int adresse, taille, temp;
struct noeud* suivant;
} * liste;
int random(int a, int b)
{
return (a + (rand() % ((b + 1) + a)));
}
void initialisation(liste* LBO)
{
*LBO = NULL;
}
I think it's here the problem when I create q (q is created to point to the previous node).
void creation(liste* LBO)
{
liste q, prec = NULL;
int i = 0;
srand(time(NULL));
while (i < 3)
{
printf("%d", i);
q = malloc(sizeof(liste));
if (*LBO == NULL)
{
q->adresse = 0;
q->taille = random(5, 45);
q->temp = random(5, 15);
q->suivant = *LBO;
*LBO = q;
i++;
}
else
{
prec = *LBO;
q->taille = random(5, 45);
q->temp = random(5, 15);
q->adresse = prec->adresse + prec->taille;
q->suivant = *LBO;
*LBO = q;
i++;
}
}
}
void affichage(liste LBO)
{
printf("\nvoici ta liste \n ");
while (LBO != NULL)
{
printf("%d-->", LBO->taille);
LBO = LBO->suivant;
}
if (LBO == NULL)
printf("NULL");
}
int main()
{
// or here
printf("Hello world!\n");
liste LBO;
initialisation(&LBO);
creation(&LBO);
affichage(LBO);
return 0;
}
There are several issues:
Instead of calling
initialisation(&LBO);
which is not really wrong, just write:
LBO = NULL;
Then don't hide pointers with typedefs, it only adds confusion.
Instead of:
typedef struct noeud
{
int adresse, taille, temp;
struct noeud* suivant;
} *liste;
Write:
struct noeud
{
int adresse, taille, temp;
struct noeud* suivant;
};
and use struct noeud* instead of liste.
Now the real problem:
This is wrong. Here you allocate the size for a pointer, but you need to allocate the size for the whole structure:
q = malloc(sizeof(liste));
which is actually the same as:
q = malloc(sizeof(struct noeud*))
but you need:
q = malloc(sizeof(struct noeud))
You see now why hiding pointers with typedefs is a bad idea.
So here is the corrected version of your program (#includes ommitted for brevity):
struct noeud
{
int adresse, taille, temp;
struct noeud* suivant;
};
int random(int a, int b)
{
return (a + (rand() % ((b + 1) + a)));
}
void creation(struct noeud** LBO)
{
struct noeud* q, *prec = NULL;
int i = 0;
// srand(time(NULL)); <<<<< don't call srand here, call it once at the
// beginning of the program
while (i < 3)
{
printf("%d", i);
q = malloc(sizeof(struct noeud));
if (*LBO == NULL)
{
q->adresse = 0;
q->taille = random(5, 45);
q->temp = random(5, 15);
q->suivant = *LBO;
*LBO = q;
i++;
}
else
{
prec = *LBO;
q->taille = random(5, 45);
q->temp = random(5, 15);
q->adresse = prec->adresse + prec->taille;
q->suivant = *LBO;
*LBO = q;
i++;
}
}
}
void affichage(struct noeud* LBO)
{
printf("\nvoici ta struct noeud* \n ");
while (LBO != NULL)
{
printf("%d-->", LBO->taille);
LBO = LBO->suivant;
}
// if (LBO == NULL) <<<<<<<<<<< drop this, LBO is always NULL here
// but it doesn't hurt, it's just useless
printf("NULL");
}
int main()
{
srand(time(NULL)); // <<<<<<<<<<<<< call srand here
struct noeud* LBO;
LBO = NULL;
creation(&LBO);
affichage(LBO);
return 0;
}
There is still room for improvement, especially the creation function is somewhat awkward.
Also look at the comments with <<<<<<<<<<<, there are minor corrections
I have a program in C which reads definition of graph from file, search for Hamiltonian cycle (only one) and prints it on screen if found. Problem is that program is crashing when I'm trying to find cycle in graphs with 30 and more vertices (for 30 vertices it sometimes shows cycle end get crashed (with different saturations), for more get crashed instantly). When I try to debug it stops at free() function and shows SIGTRAP signal. What can I do to fix that? Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
typedef struct Lista
{
struct Lista * next;
int v;
} Lista;
Lista * stos;
bool *visited;
int wierzcholki, krawedzie;
int *S;
int sptr;
Lista **graf;
bool czyZnaleziono = false;
int DFSHamilton(int v)
{
if (!czyZnaleziono)
{
int i;
bool test;
Lista *p;
S[sptr++] = v;
if(sptr < wierzcholki)
{
visited[v] = true;
for(p = graf[v]; p; p = p->next)
if(!visited[p->v]) DFSHamilton(p->v);
visited[v] = false;
}
else
{
test = false;
for(p = graf[v]; p; p = p->next)
if(!(p->v))
{
test = true;
break;
}
if(test)
{
printf("Hamiltonian Cycle : ");
for(i = 0; i < sptr; i++)
{
printf("%d ",S[i]);
}
printf("0\n");
czyZnaleziono = true;
}
}
sptr--;
}
}
int main()
{
FILE *plik;
Lista *p, *r;
plik = fopen("rzeczy40-95.txt", "r");
double start, stop, czas;
int i, j, w1, w2;
sptr = 0;
visited = malloc(krawedzie*sizeof(bool));
if (plik == NULL)
{
printf("Nie mozna odnalezc pliku");
return 0;
}
else
{
fscanf(plik, "%d %d", &wierzcholki, &krawedzie);
S = malloc(wierzcholki*sizeof(int));
graf = malloc(wierzcholki*sizeof(Lista));
for(i=0; i<wierzcholki; i++)
{
graf[i] = NULL;
visited[i] = false;
}
for(j=0; j<krawedzie; j++)
{
fscanf(plik,"%d %d", &w1, &w2);
p = malloc(sizeof(Lista));
r = malloc(sizeof(Lista));
p->v = w2;
p->next = graf[w1];
graf[w1] = p;
r->v = w1;
r->next = graf[w2];
graf[w2] = r;
}
fclose(plik);
DFSHamilton(0);
free(visited);
free(S);
for (i = 0; i < wierzcholki; i++)
{
free(graf[i]);
}
free(graf);
return 0;
}
}
So I'm having trouble with Dijkstra's algorithm (src to dest). I looked at other answers and could not find the solution to my problem. I have used an adjacency list, thus I have a list for vertices, and each vertex has it's own edge list. My problem arises when I have a node that is unreachable. Specifically, it never gets visited thus I'm stuck in my allNotComp while loop. Can anyone help me with a solution? Code is below.
#include <stdlib.h>
#include <stdio.h>
int INFINITY = 9999;
struct edge
{
int vertexIndex;
int vertexWeight;
struct edge *edgePtr;
} edge;
struct vertex
{
int vertexKey;
struct edge *edgePtr;
struct vertex *vertexPtr;
}vertex;
struct vertex *Start = NULL;
void insertEdge(int vertex, int vertex2, int vertexWeight);
void insertVertex(int vertexKey);
int allNotComp(int comp[], int size);
void printPath(int prev[], int src, int dest, int size);
void dijkstra(int src, int size, int dest);
int cost(int curr, int i);
int main(int argc, char * argv[]) {
int k = 1;
int numVertices = atoi(argv[2]);
char* source = argv[3];
char* destination = argv[4];
int src = atoi(argv[3]);
int dest = atoi(argv[4]);
Start = &vertex;
Start->vertexKey = 0;
Start->vertexPtr = NULL;
Start->edgePtr = NULL;
int m = 0;
int flag = 0;
int flag2 = 0;
for(m = 0; m < numVertices; m++){
if(src == m) {
flag = 1;
}
if(dest == m) {
flag2 = 1;
}
}
if(!(flag && flag2)) {
printf("%s ", "ERROR: Src and/or Dest not valid.\n");
exit(0);
}
while(k < numVertices) {
insertVertex(k);
k++;
}
FILE *f = fopen(argv[1], "r");
int numbers[numVertices][numVertices];
char ch;
int i = 0;
int j = 0;
for(m = 0; m < numVertices*numVertices; m++) {
fscanf(f, "%d", &(numbers[i][j]));
j=j+1;
if(j == numVertices) {
i=i+1;
j=0;
}
}
for(i=0;i<numVertices;i++) {
for(j=0;j<numVertices;j++) {
if(i == j && numbers[i][j] != 0) {
printf("%s", "ERROR: All diagonals must be zero.\n");
exit(0);
}
if(i != j) {
insertEdge(i, j, numbers[i][j]);
}
}
}
dijkstra(src, numVertices, dest);
}
void insertEdge(int vertex, int vertex2, int vertexWeight)
{
if(vertexWeight == -1) return;
struct vertex *traverse;
if(vertex == Start->vertexKey) {
traverse = Start;
}
else {
while(traverse->vertexKey != vertex) {
traverse = traverse->vertexPtr;
}
}
struct edge *e,*e1,*e2;
e=traverse->edgePtr;
while(e&& e->edgePtr)
{
e=e->edgePtr;
}
e1=(struct edge *)malloc(sizeof(*e1));
e1->vertexIndex=vertex2;
e1->vertexWeight = vertexWeight;
e1->edgePtr=NULL;
if(e)
e->edgePtr=e1;
else
traverse->edgePtr=e1;
}
void insertVertex(int vertexKey) {
struct vertex *v, *v1, *v2;
v = Start->vertexPtr;
while(v && v->vertexPtr) {
v=v->vertexPtr;
}
v1=(struct vertex *)malloc(sizeof(*v1));
v1->vertexKey = vertexKey;
v1->vertexPtr = NULL;
v1->edgePtr = NULL;
if(v) {
v->vertexPtr = v1;
}
else {
Start->vertexPtr = v1;
}
}
void dijkstra(int src, int size, int dest) {
int comp[size];
int dist[size];
int prev[size];
int i;
for(i = 0; i<size; i++) {
comp[i] = 0;
dist[i] = INFINITY;
prev[i] = -1;
}
comp[src] = 1;
dist[src] = 0;
prev[src] = src;
int curr = src;
int k;
int minDist;
int newDist;
while(allNotComp(comp, size)) {
minDist = INFINITY;
for(i = 0; i<size;i++) {
if(comp[i] == 0) {
newDist = dist[curr] + cost(curr, i);
if(newDist < dist[i]) {
dist[i] = newDist;
prev[i] = curr; }
if(dist[i] < minDist) {
minDist = dist[i];
k=i; }
}
}
curr = k;
comp[curr] = 1;
}
if(dist[dest] < INFINITY) {
printPath(prev, src, dest, size);
printf(":%d\n", dist[dest]);
} else {
printf("%s\n", "NO PATH EXISTS BETWEEN THE TWO VERTICES!");
}
}
int allNotComp(int comp[], int size) {
int i;
for(i = 0; i < size; i++) {
if(comp[i] == 0) {
return 1;
}
}
return 0;
}
int cost(int curr, int i) {
struct vertex *travel;
struct edge *traverse;
travel = Start;
while(travel->vertexPtr != NULL) {
if(travel->vertexKey != curr) {
travel = travel->vertexPtr;
}
else{
break;
}
}
traverse = travel->edgePtr;
while(traverse->edgePtr != NULL) {
if(traverse->vertexIndex != i) {
traverse = traverse->edgePtr;
}
else{
break;
}
}
if(traverse->vertexIndex != i) {
return INFINITY;
}
return traverse->vertexWeight;
}
void printPath(int prev[], int src, int dest, int size) {
if(src == dest) {
printf("%d", src);
}
else {
printPath(prev, src, prev[dest], size);
printf("-%d", dest);
}
}
Although an unreachable node never gets visited, this situation can be detected. If the dists of all unvisited nodes are INFINITY, this means all remaining nodes are unreachable, and you should end the loop.