The edges printed does not match the nodes - c

I have a program that reads a file with two columns of numbers, sorts them, creates three tables, one with only the nodes (individually), one with all the edges and one that has the amount of edges for every node. The problem is that when I try to print the edges, it prints them wrong or it says it cannot find them. Through some gdb I found out that the first arrays are fine but the third stores a bunch of random numbers (or zeros) through the end. Any help would be appreciated.
The file looks like this (start/end node for each edge):
7856 8192
7754 7005
7862 1982
7862 3293
7862 4037
7862 5210
7862 5605
7862 7860
The code looks like this:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int mapcmp(const void *a,const void *b){
return ( *(int*)a - *(int*)b );
}
int mapdoublesize(int** map,int nodes){
int* new_array=malloc(nodes*2*sizeof(int));
if(new_array==NULL){
printf("Error allocating memory\n");
abort();
}
nodes*=2;
for(int i=0;i<nodes;i++){
new_array[i]=(*map)[i];
}
free(*map);
*map=new_array;
return nodes;
}
typedef struct {
int start;
int end;
} path;
int cmp(const void *a,const void *b){
int l=((path*)a)->start;
int r=((path*)b)->start;
if(l>r)
return 1;
if(l<r)
return -1;
if(l==r)
return 0;
}
int doublesize(path** array,int n){
path* new_array=malloc(n*2*sizeof(path));
if(new_array==NULL){
printf("Error allocating memory\n");
abort();
}
for(int i=0;i<n;i++){
new_array[i]=(*array)[i];
}
free(*array);
*array=new_array;
n*=2;
return n;
}
int main()
{
int maxsize=10;
int test;
path* array=malloc(maxsize*sizeof(path));
if(array==NULL) {
printf("Error allocating memory\n");
abort();
}
FILE* fd=fopen("Wiki-Vote.txt","r");
if(fd==NULL) {
printf("Error opening file\n");
abort();
}
char buff[200];
int counter=0;
char c;
while(fgets(buff,200,fd)) {
c=buff[0];
if(c=='#') {
continue;
}
sscanf(buff,"%d%d",&array[counter].start,&array[counter].end);
counter++;
if(counter==maxsize){
maxsize=doublesize(&array,maxsize);
}
}
int i;
maxsize=counter;
counter=0;
qsort(&array[0],maxsize,sizeof(path),cmp);
counter=0;
int nodes=10;
int* map=malloc(nodes*sizeof(int));
if(map==NULL){
printf("Error allocating memory\n");
abort();
}
for(i=0;i<maxsize;i++){
if(map[counter-1]==array[i].start)
continue;
map[counter]=array[i].start;
counter++;
if(counter==nodes){
nodes=mapdoublesize(&map,nodes);
}
}
int j;
for(i=0;i<maxsize;i++){
for(j=0;j<counter;j++){
if(map[j]==array[i].end)
break;
}
if(j!=counter)
continue;
map[counter]=array[i].end;
counter++;
if(counter==nodes)
nodes=mapdoublesize(&map,nodes);
}
nodes=counter;
qsort(&map[0],nodes,sizeof(int),mapcmp);
int* arraynodes=malloc(nodes*sizeof(int));
int* arrayedges=malloc(maxsize*sizeof(int));
if(arraynodes==NULL||arrayedges==NULL){
printf("Error allocating memory\n");
abort();
}
counter=1;
arraynodes[0]=0;
for(i=0;i<maxsize;i++){
arrayedges[i]=array[i].end;
if(array[i].start!=array[i+1].start){
arraynodes[counter]=i;
counter++;
}
}
int x;
printf("give number to search: ");
scanf("%d",&x);
for(i=0;i<nodes;i++){
if(x==map[i]){
printf("found \n");
break;
}
}
if(i==nodes){
printf("not found \n");
abort();
}
for(j=arraynodes[i];j<arraynodes[i+1];j++){
printf("%d\n",arrayedges[j]);
}
free(arraynodes);
free(arrayedges);
free(map);
fclose(fd);
free(array);
return 0;
}

Core answer:
As I understand your intention, you want arraynodes to hold for each node index the offset in the edge list where the edges for that node start.
You iterate over the edge list and every time the starting point changes, you store the current offset in arraynodes. This is flawed, because not all nodes are the starting point of an edge. So if your edge list has an edge from node 5 -> 7 and then an edge from 6 -> 7 then you will register the change of the starting point from 5 to 6, but you will store the current offset at the beginning of arraynodes and not for the 5th node.
To fix this, instead do this: Keep an offset into the edge list, initially zero. Iterate over the nodes, for each node store the current offset into arraynodes. Then increment the offset as long as the starting point of the edge at the current offset is equal to the current node. This way arraynodes will tell you for each node index, at which index in the edge list the edges starting at this node are stored.
/**
* Assumption: Edges are sorted by their starting point.
*/
int edge_count = maxsize;
int edge_offset = 0;
/**
* For each node:
*
* - Store current edge_offset in arraynodes
* - Increment edge_offset as long as the start point
* of the edge at that offset matches the current node.
*/
for (int i = 0; i < nodes; i++) {
int current_node = map[i];
arraynodes[i] = edge_offset;
while (edge_offset < edge_count && array[edge_offset].start == current_node) {
edge_offset++;
}
}
/**
* Copy end-points of edges to arrayedges.
*
* You don't really need this, you could also directly
* access the end-points in your output loop ...
*/
for (int i = 0; i < edge_count; i++) {
arrayedges[i] = array[i].end;
}
Memory safety issues:
There are a several memory safety issues in your code:
Buffer underflow: In the first pass of the loop, counter is zero, so map[counter-1] goes out of bounds.
counter = 0;
int nodes = 10;
int *map = malloc(nodes * sizeof(int));
if (map == NULL) {
printf("Error allocating memory\n");
abort();
}
for (i = 0; i < maxsize; i++) {
if (map[counter - 1] == array[i].start)
continue;
Buffer overflow: When you initialize the map, you want to double its size when it's full. However, in mapdoublesize when you copy the data from the old map to the new map, you iterate over the whole new map, so the second half of this loop reads past the bounds of the old map:
nodes *= 2;
for (int i = 0; i < nodes; i++) {
new_array[i] = (*map)[i];
}
Buffer overflow: In the last iteration of this loop: The access to array[i+1] is out of bounds:
for (i = 0; i < maxsize; i++) {
arrayedges[i] = array[i].end;
if (array[i].start != array[i + 1].start) {
Buffer overflow: In your output loop, if i is the last node, your access to arraynodes[i+1] goes out of bounds:
for (j = arraynodes[i]; j < arraynodes[i + 1]; j++) {
I do not guarantee that I found all memory safety issues. There might very well be more. I would advice you to improve the structuring and documentation of your program: Break down your program into smaller functions that do one step and document the assumptions and preconditions of this step (i.e. what are the bound of the array you are accessing?). Give the variables names that cleary describe their purpose, do not reuse variables. This should make it easier for you to spot these kinds of errors. Also I would advice you to use tools to check for memory safety issues. GCC and Clang both have a feature called ASAN that will automatically insert debug code into your binary that will detect and report memory safety issues when you run your program. You can enable this by compiling with -fsanitize=address (reference). Another tool with a similar scope would be Valgrind (reference). These programs cannot find all errors of course, since they only do dynamic analysis of the code that is actually executed. If there is a bug in some branch of your program that is not reached by the current execution, it will not be detected. So you still do not get around taking a careful look at your program.

Related

Leetcode Segmentation fault trying to reset hashtable data structure between calls (partially solved)

I'm doing a problem on Leetcode. It says I passed my first test case but I failed my second with a simple wrong answer. When I ran that case manually, I passed, so I know it's something to do with data persistence between their runs. It's obviously the hash table I'm using, which I first declared globally. To fix, I first tried resetting to zero with calloc and memset but I got segfault errors.
I decided the logical thing is to create the hash inside the caller function, so each time it's called it would be reinitalized. However, I am still getting seg fault errors (address sanitizer deadly signal) even though it seems like it should work. Am I misusing pointers?
Here is my code that's not working. The comments //\ represent lines of code I had before, where it did work case by case. There were not many changes- mostly to return the hash. I comment where the seg fault occurs (per my printf debugging). I hope I didn't miss anything. I'm trying to display two coding instanecs in one because it's mostly reduntant.
#define SIZE 1000
typedef struct htent{
struct htent* next;
int key, value;
} htent;
int hashf(int val, int size){
return val % SIZE; // don't need anything fancy
}
htent* create_new_htent(int val){ // the value is its own key
htent* ent = malloc(sizeof(htent));
ent->next = NULL;
ent->key = val;
ent->value = val;
return ent;
}
// htent* ht[SIZE] = {0}; //\\ This was my method before (main difference)
htent* build_hash_table_n_get_lowest(int* nums, int numsSize, int* low){ //\\ returned void before
htent* ht[SIZE] = {0}; //\\ before was commented out
int hash;
int running_low = 10000; // large #
htent* tmp;
for (int i = 0; i < numsSize; i++){
if (nums[i] < 1 ) continue; // drop negatives
if (nums[i] < running_low) running_low = nums[i];
printf("%d: Running Low %d\n", i, running_low);
htent* ent = create_new_htent(nums[i]);
hash = hashf(nums[i], numsSize);
if (ht[hash] == NULL){
ht[hash] = ent; // singly linked list
continue;
}
tmp = ht[hash];
while(tmp->next != NULL){
tmp = tmp->next;
}
tmp->next = ent;
}
*low = running_low;
return ht; //\\ was commented out before
}
int find_missing_lowest(htent** ht, int numsSize, int lowest){
int moving_target = 1;
for (int i = 0; i<numsSize; i++){
if (ht[moving_target] == NULL){ // SEG FAULTS HERE!!!
return moving_target;
}
moving_target++;
}
return moving_target;
}
int firstMissingPositive(int* nums, int numsSize){ // Function Leetcode calls
int lowest;
htent* ht = build_hash_table_n_get_lowest(nums, numsSize, &lowest); // tried with htent**
return find_missing_lowest(ht, numsSize, lowest);
}
EDIT: I built this function using the global scope approach and it works and these tests pass (just have to handle edge cases), but there has to be a better way;
void refresh_hashtable(){
for (int i = 0; i<SIZE; i++){
ht[i] = NULL;
}
}

Why is Valgrind finding errors in this hash table test case?

I took it upon myself to develop a concurrent generic hash table in C.
Relevant contents of hash_table.h:
typedef struct list_node {
void * data;
struct list_node * next;
} list_node_t;
typedef struct hash_table {
int max_size;
int count;
list_node_t * * elements;
pthread_rwlock_t * locks;
pthread_rwlock_t global_table_lock;
hash_table_compare_function compare;
hash_table_hash_function hash;
} hash_table_t;
Relevant contents of hash_table.c:
#define LOCK_RD(lock) pthread_rwlock_rdlock(&lock);
#define LOCK_WR(lock) pthread_rwlock_wrlock(&lock);
#define UNLOCK(lock) pthread_rwlock_unlock(&lock);
bool
hash_table_remove(hash_table_t * table, void * element)
{
int hash_value = table->hash(element);
list_node_t * node, * prev;
LOCK_WR(table->locks[hash_value]);
node = table->elements[hash_value];
prev = NULL;
while (node) {
if (!table->compare(node->data, element)) {
// value is first item in the list
if (node == table->elements[hash_value]) {
table->elements[hash_value] = node->next;
free(node);
UNLOCK(table->locks[hash_value]);
LOCK_WR(table->global_table_lock);
table->count--;
UNLOCK(table->global_table_lock);
return true;
} else {
// link previous node with one after current
prev->next = node->next;
free(node);
UNLOCK(table->locks[hash_value]);
LOCK_WR(table->global_table_lock);
table->count--;
UNLOCK(table->global_table_lock);
return true;
}
}
prev = node;
node = node->next;
}
UNLOCK(table->locks[hash_value]);
return false;
}
I wrote a test case which uses strings, in which this is the relevant code:
#include "hashtable.h"
#define NUM_THREADS 2
#define NUM_STRINGS 154560
#define NUM_LOOKUPS 10000
void *
do_work(void * data)
{
int thread_id = *(int*)data;
// write "threadX.txt" to filename, where X is the given thread id
char filename[64];
strcpy(filename, "thread");
char thread_id_str[4];
sprintf(thread_id_str, "%d", thread_id);
strcat(filename, thread_id_str);
strcat(filename, ".txt");
FILE * file = fopen(filename, "r");
char buffer[128];
int i, num_str_per_thread = NUM_STRINGS / NUM_THREADS;
char * str_array[num_str_per_thread];
for (i = 0; i < num_str_per_thread; i++) {
fgets(buffer, 128, file);
str_array[i] = calloc((strlen(buffer) + 1), sizeof(char));
strcpy(str_array[i], buffer);
}
fclose(file);
for (i = 0; i < num_str_per_thread; i++)
hash_table_insert(table, str_array[i]);
for (i = 0; i < NUM_LOOKUPS; i++)
hash_table_contains(table, str_array[rand() % num_str_per_thread]);
for (i = 0; i < num_str_per_thread / 2; i++)
hash_table_remove(table, str_array[rand() % num_str_per_thread]);
//sleep(2); NOTE: no read errors reported if I leave this sleep() here.
for (i = 0; i < num_str_per_thread; i++)
if (str_array[i])
free(str_array[i]);
return NULL;
}
void
create_workers()
{
pthread_t threads[NUM_THREADS];
int ids[NUM_THREADS];
int i;
for (i = 0; i < NUM_THREADS; i++)
ids[i] = i + 1;
for (i = 0; i < NUM_THREADS; i++)
pthread_create(&threads[i], NULL, do_work, (void*)&ids[i]);
for (i = 0; i < NUM_THREADS; i++)
pthread_join(threads[i], NULL);
}
The test case is supposed to work as follows: there are two files, thread1.txt and thread2.txt, each containing unique strings I have generated beforehand. I create two threads, and each will read from a file and store each string on an array of strings called str_array. They will then insert all these strings into the hash table and perform random searches (hash_table_contains) and deletions (hash_table_remove). Then, each will free their respective array of strings. However, when I run this test case, Valgrind reports the following:
Please note that there are no memory leaks. What I get from these errors is that a thread is, upon calling hash_table_remove, attempting to free memory already freed by free(str_array[i]). However, that makes no sense, since hash_table_remove is called before free(str_array[i]. I can't figure out what's giving me these invalid reads.
Thank you in advance!
Here, your thread removes at most half the strings it inserted:
for (i = 0; i < num_str_per_thread / 2; i++)
hash_table_remove(table, str_array[rand() % num_str_per_thread]);
(in fact, it is most likely to remove about 39% of the strings it inserted).
Then, it goes on to free all the strings it inserted:
for (i = 0; i < num_str_per_thread; i++)
if (str_array[i])
free(str_array[i]);
However, at least half (and most likely ~61%) of those strings are still in the hash table, where the other threads will try to compare them as they scan through the chained hash bucket entries. That's your use-after-free error.
Instead of freeing all the strings, you could free them as you remove them:
for (i = 0; i < num_str_per_thread / 2; i++)
{
int str_index = rand() % num_str_per_thread;
if (str_array[str_index])
{
hash_table_remove(table, str_array[str_index]);
free(str_array[str_index]);
str_array[str_index] = NULL;
}
}
At this point, the non-NULL entries in str_array[] are the strings still present in the hash table. You can't free them until they're removed from the hash table (or the hash table is no longer in use).
The fact that your test case got this wrong is a good indicator that the ergonomics of your interface are not as good as they could be. You should probably consider a design in which the ownership of the strings inserted is transferred to the hash table, so that hash_table_remove() is itself responsible for freeing the string.

array of linked list for hash table

I want to know about bring the text file with 10 names and read it. 10 names are sorting by descending and forming a hash table with division method. I need to construct linked list of them. The hash table's index is number of 7.
I've tried on match pointer variable and made a hash table, but I can't do that. I'm in trouble with making hash table, inserting data, printing hash table and searching data(A function to find when I type a name.). I need to add more function..how do i made it?
#define SIZE 7
struct node {
char data[100][20];
struct node* next;
};
struct index {
struct node* head;
int count;
};
struct sum (data){
struct node* ptr;
int sum,i;
for (i=0; i<20; i++) {
ptr -> data[i] = ptr;
strcpy(sum,ptr);
}
return sum;
};
int hashFunction (int sum) {
return sum%SIZE;
}
void descend (data) {
int temp;
for(i=0;i<100;i++) {
for(j=0;j=20;j++) {
if (data[i][j+1]>data[i][j])
temp=data[i][j];
data[i][j]=data[i][j+1];
data[i][j+1]=temp;
}
}
}
int main (void) {
char data[100][20];
FILE *fp;
fp = fopen("data.txt","r");
for (int i=0; i<20; i++)
fscanf (fp,"%s",&data);
printf("%s\n",data);
}
fclose(fp);
hashTable = (struct index*)malloc(SIZE*sizeof(struct index));
descend(data);
return 0;
}
There are lot of bugs in the code, I'm just putting my possible observation. Firstly this
fscanf (fp,"%s",&data);
should be
fscanf (fp,"%s",&data[i]);
Secondly, here in descend() function inner loop condition part you are using j=20 which loops to run infinitely. This is where MACRO comes handy as this j=20 simply runs i.e if it could have ROW=j where ROW is 20 compiler produces meaningful error. This
void descend (data) { /* what is the tyep of data ? you should mention the data type */
int temp;
for(i=0;i<100;i++) { /* there are only 20 lines not 100 i.e it should be i<20 */
for(j=0;j=20;j++) { /* condition is wrong, you indented for j<20 but that too
wrong as there are supposed to be max 100 char in line
it should be j<100 */
if (data[i][j+1]>data[i][j]) /* condition is not correct */
temp=data[i][j];
data[i][j]=data[i][j+1];
data[i][j+1]=temp;
}
}
}
Correct version descend function can be
void descend (char (*data)[ROW], int col) { /* define ROW as macro with value 20 and pass the col i.e 100 */
int temp;
for(i=0;i < ROW; i++) {
for(j=0;j < col; j++) {
if (data[i][j] > data[i][j+1])
temp = data[i][j];
data[i][j] = data[i][j+1];
data[i][j+1] = temp;
}
}
}
Also check the return value of fopen() to check whether it was success r failed and do proper validation. For e.g
fp = fopen("data.txt","r");
if(fp == NULL) {
/* #TODO error handling */
fprintf(stderr,"file doesn't exist");
return 0;
}
To begin with, it looks like you should declare char data[20][100] instead of char data[100][20].
Then, inside the loop of 20 iterations, you should refer to data[i] instead of data:
for (int i=0; i<20; i++)
fscanf(fp,"%s",data[i]);
printf("%s\n",data[i]);
}
Keep in mind you're assuming that each line in your input file is at most 99-character long.
This doesn't answer the actual question I suppose, but you should by the least get all the above fixed.

Values change after calling function in C

I'm trying to make a file system in C. I have trouble with this portion of my code when I'm printing my values in the code below:
for (int i = 0; i<NUM_POINTERS; i++) {
printf("before SB->root[%d]=%d\n", i, SB->root->pointers[i]);
}
write_blocks(0, 1, SB);
for (int i = 0; i<NUM_POINTERS; i++) {
printf("after SB->root[%d]=%d\n", i, SB->root->pointers[i]);
}
my write_blocks method:
int write_blocks(int start_address, int nblocks, void *buffer)
{
int i, e, s;
e = 0;
s = 0;
void* blockWrite = (void*) malloc(BLOCK_SIZE);
/*Checks that the data requested is within the range of addresses of the disk*/
if (start_address + nblocks > MAX_BLOCK)
{
printf("out of bound error\n");
return -1;
}
/*Goto where the data is to be written on the disk*/
fseek(fp, start_address * BLOCK_SIZE, SEEK_SET);
/*For every block requested*/
for (i = 0; i < nblocks; ++i)
{
/*Pause until the latency duration is elapsed*/
usleep(L);
memcpy(blockWrite, buffer+(i*BLOCK_SIZE), BLOCK_SIZE);
fwrite(blockWrite, BLOCK_SIZE, 1, fp);
fflush(fp);
s++;
}
free(blockWrite);
/*If no failure return the number of blocks written, else return the negative number of failures*/
if (e == 0)
return s;
else
return e;
}
And here's what gets printed:
before SB->root[0]=1
before SB->root[1]=2
before SB->root[2]=3
before SB->root[3]=4
before SB->root[4]=5
before SB->root[5]=6
before SB->root[6]=7
before SB->root[7]=8
before SB->root[8]=9
before SB->root[9]=10
before SB->root[10]=11
before SB->root[11]=12
before SB->root[12]=13
before SB->root[13]=14
after SB->root[0]=1234344888
after SB->root[1]=32688
after SB->root[2]=3
after SB->root[3]=4
after SB->root[4]=5
after SB->root[5]=6
after SB->root[6]=7
after SB->root[7]=8
after SB->root[8]=9
after SB->root[9]=10
after SB->root[10]=11
after SB->root[11]=12
after SB->root[12]=13
after SB->root[13]=14
I don't understand why my first and second pointer value change?
Some additional information: SB is a superBlock here's my structures:
typedef struct iNode
{
int id;
int size;
int pointers[NUM_POINTERS];
} iNode;
typedef struct superBlock
{
int magic_number;
int block_size;
int num_blocks;
int num_inodes;
iNode *root;
iNode jNodes[20];
} superBlock;
Is this single threaded?
Does the modified SB->root[0,1] contain the data you are trying to write?
What is your BLOCK_SIZE?
I suspect the problem is outside of write_blocks(). My best guess would be that you accidentally freed SB somewhere and malloc gave you the same address. After the malloc check (print or debugger) both buffer and blockWrite and make sure they are different and valid.
Unrelated Issues:
printf has more % than params
You should check the return of malloc
e is never set
s and i are equal. AKA redundant.
Out of bounds error causes a memory leak (since it is after the malloc)
usleep is strange perhaps you want fsync?

Not able to get result out of my adjaceny matrix code for declaring graph

I have written acode for adjacency matrix for graph declaration. It compiles successfully with no errors. But when i run the code and entered the values, my code get crahes out only after reading the values of number of edges and vertex i.e v & e.
I am not able to input the values for edges i.e u & v. Need help.
#include<stdio.h>
struct Graph
{
int v;
int e;
int **Adj;
};
struct Graph *adjMatrixOfGraph()
{
int i,u,v;
struct Graph *G = (struct Graph *)malloc(sizeof(struct Graph));
if(!G)
{
printf("Memory Error");
return 0;
}
scanf("Number of Vertices:%d Number of Edges:%d",&G->v,&G->e);
G->Adj = (int** )malloc(sizeof(G->v*G->v));
G->Adj =(int **) malloc(G->v*sizeof(int*));
for ( i = 0; i < G->v; ++i)
{
*(G->Adj+i) = (int*) malloc(G->v*sizeof(int));
}
for(u=0;u<G->v;u++)
{
for(v=0;v<G->v;v++)
{
G->Adj[v][v]=0;
}
}
for(i=0;i<G->v;i++)
{
scanf("Reading Edge:%d %d",&u,&v);
G->Adj[u][v]=1;
G->Adj[v][u]=1;
}
return G;
}
int main()
{
int a;
struct Graph *p = adjMatrixOfGraph();
int u,v;
p->Adj = malloc(sizeof(p->v*p->v));
for(u=0;u<p->v;u++)
{
for(v=0;v<p->v;v++)
{
if(p->Adj[u][v]==1)
printf("\n there is an edge from%d",u,"---------->%d",v);
}
}*/
return 0;
}
Solution
Use simple scanf..Dont get the "Give edges .." etc in scanf. Simply use scanf("%d %d",&u,&v);
for(i=0;i<G->v;i++)
{
//scanf("Reading Edge:%d %d",&u,&v);
if(scanf("%d %d",&u,&v)==2){//works
..
}
...
}
Otherwise scanf expects you to type those letters exactly from the standard input.
for(i=0;i<G->e;i++)
{
if(scanf("Reading Edge:%d %d",&u,&v)!=2){ //debug; }
G->Adj[u][v]=1;
G->Adj[v][u]=1;
}
Take edges not vertices number of inputs.
As 4386427..add a check in scanf .. it is good practice and effective one too.
Not sure that this is the reason for your crash but you have a number of strange things in your code.
1) Always check scanf return value
if (scanf("Number of Vertices:%d Number of Edges:%d",&G->v,&G->e) != 2)
{
// Add error handling
}
2) Memory leak
G->Adj = (int** )malloc(sizeof(G->v*G->v));
G->Adj =(int **) malloc(G->v*sizeof(int*));
Here you assign to G->Adj twice and thereby causes memory leak. Further the first allocation looks wrong as it doesn't use sizeof a type.
3) Scanned value not used, i.e. G->e is never used.
4) Strange index
for(u=0;u<G->v;u++)
{
for(v=0;v<G->v;v++)
{
G->Adj[v][v]=0;
}
}
Here you never use u for index. Should it be: G->Adj[u][v]=0;
5) Another memory leak in main
p->Adj = malloc(sizeof(p->v*p->v));
Again you overwrite Adj and causes memory leak. The sizeof(p->v*p->v) looks strange. Should it be sizeof(int*)*p->v*p->v? Further all initialization done in the function is lost. This means that you have undefined behavior when you start accessing data as int. Perhaps, you shouldn't at all do the malloc in main.
This time we seem to need 3 answers. ;)
While 4386427 addresses the memory leaks and incorrect allocation style, Coderredoc addressed the wrong usage of scanf and loop variables.
Additionally printf is called incorrectly:
printf("\n there is an edge from%d",u,"---------->%d",v);
These are 3 arguments for 1 format specifier. It should be changed to
printf("\n there is an edge from %d---------->%d",u,v);
If you take care of all 3 answers your code should work.
Finally, from going through all the suggestion made above, ihave updated my code to as below.But the problem persist.
#include<stdio.h>
#include<stdlib.h>
//using namespace std;
struct Graph
{
int v;
int e;
int **Adj;
};
struct Graph *adjMatrixOfGraph()
{
int i,u,v;
struct Graph *G = (struct Graph *)malloc(sizeof(struct Graph));
if(!G)
{
printf("Memory Error");
return 0;
}
scanf("%d %d",&G->v,&G->e);
G->Adj= malloc(G->v * sizeof(int *));
for(i = 0; i < G->v; i++) {
G->Adj[i] = malloc(G->v * sizeof(int));
}
for(u=0;u<G->v;u++)
{
for(v=0;v<G->v;v++)
{
G->Adj[v][v]=0;
}
}
for(i=0;i<G->v;i++)
{
scanf("%d %d",&u,&v);
G->Adj[u][v]=1;
G->Adj[v][u]=1;
}
return G;
}
int main()
{
int a;
int i;
struct Graph *p = adjMatrixOfGraph();
// printf("Number of Vertices:%d, Number of Edges:%d",p->v,p->e);
int u,v;
p->Adj= malloc(p->v * sizeof(int *));
for(i = 0; i < p->v; i++) {
p->Adj[i] = malloc(p->v * sizeof(int));
}
for(u=0;u<p->v;u++)
{
for(v=0;v<p->v;v++)
{
if(p->Adj[u][v]==1)
printf("\n there is an edge from%d",u,"---------->%d",v);
}
}
return 0;
}

Resources