overexchange overexchange - 1 month ago 17
C Question

Program receives signal - gdb

For the below question,

Exercise 12335 - Write a C program to read through an array of any type. Write a C program to scan through this array to find a particular value.


Here is my solution:

#include<stdio.h>
enum types
{
integer,
character,
floatValue
};
void f(void *, enum types);
void doSomething(void *, enum types);
int main(){
int a[] ={1,2,3};
enum types type = integer;
f(a, type);
}

void f(void *ptr, enum types type){
switch(type){
case(integer):
if(sizeof((int *)ptr)/sizeof(int) > 1){
doSomething(&((int *)ptr)[1], type); // Print second element
}
break;
case(character):
if(sizeof((char *)ptr)/sizeof(char) > 1){
doSomething(&((int *)ptr)[1], type); // Print second element
}
break;
case(floatValue):
if(sizeof((float *)ptr)/sizeof(float) > 1){
doSomething(&((int *)ptr)[1], type); // Print second element
}
break;
}
}

void doSomething(void *ptr, enum types type){
switch(type){
case(integer):
printf("%d", *(int *)ptr);
break;
case(character):
printf("%c", *(char *)ptr);
break;
case(floatValue):
printf("%f", *(float *)ptr);
break;
}
}





> gcc -g temp.c -o program.exe
> gdb program.exe


Below is the gdb output:

enter image description here



enter image description here



Question:

Why does
program.exe
not work?

Answer

You can not find the size of an array based solely on the pointer (the pointer is only an address - it does not contain any information about what it points to).

Below is a solution where the function is modified, and the array size is passed in as a parameter.

#include<stdio.h>
enum types
  {
    integer,
    character,
    floatValue
  };
void f(void *, enum types, int a_size);
void doSomething(void *, enum types);
int main(){
  int a[] ={1,2,3};
  enum types type = integer;
  f(a, type, sizeof(a));
}

void f(void *ptr, enum types type, int a_size){
  switch(type){
    case(integer):
      if(a_size/sizeof(int) > 1){
        doSomething(&((int *)ptr)[1], type); // Print second element
      }
      break;
    case(character):
      if(a_size/sizeof(char) > 1){
        doSomething(&((int *)ptr)[1], type); // Print second element
      }
      break;
    case(floatValue):
      if(a_size/sizeof(float) > 1){
        doSomething(&((int *)ptr)[1], type); // Print second element
      }
      break;
  }
}

void doSomething(void *ptr, enum types type){
  switch(type){
    case(integer):
      printf("%d", *(int *)ptr);
      break;
    case(character):
      printf("%c", *(char *)ptr);
      break;
    case(floatValue):
      printf("%f", *(float *)ptr);
      break;
  }
}

I'm not sure if it will fix your gdb issue (I'm on Linux, not Windows, and not receiving any signals), but the program will run correctly.

[UPDATE]

This is a style thing, but I would update the f function to look like this:

void f(void *ptr, enum types type, int a_size){
  int unit_size;
  switch(type){
    case(integer):
      unit_size = sizeof(int);
      break;
    case(character):
      unit_size = sizeof(char);
      break;
    case(floatValue):
      unit_size = sizeof(float);
      break;
    default:
      break;
  }
  if((a_size/unit_size) > 1){
    doSomething(&((int *)ptr)[1], type); // Print second element
  }
}

It makes it more readable, quicker to add different types, and if you change the call to doSomething, you only have to modify it in one place.