2d array struct seg fault - c

Am I mallocing my struct correctly? If so then why is a segfault occurring after the first element. I am quite stumped on the whole pointer and dereferencing with structs.
The problem:
2x2 matrix of struct a
file fp containing the lines
5 4 3 2 1 1
11 21 1 3 2 2
Relevant code:
struct
typedef struct num{
int s;
}num_t;
In main that uses a (note n and m are ints, where in my runtime were: n = 2, m = 3)
num_t **a;
a = malloc(sizeof(num_t *) * n);
for(i=0;i<n;i++)
a[i]= malloc(sizeof(num_t) * m);
//check if mallocs suceeded
if(a==NULL)
return -1;
//read matrix.dat, check if correct size
pb = matrix(n,m,&a,*(argv+3));
My function where segfault occurs(skip to the middle of inner loop):
int matrix(int n, int m, num_t ***a, char* file)
{
int i,j,k,count;
int d,e;
char z,w;
FILE *fp;
fp = fopen(file,"r");
//check if file opened
if(fp == NULL)
{
fclose(fp);
return -1;
}
else
{
i=0;
k=0;
count=0;
for(i=0;(k!=EOF)||i<n;i++)
{
printf("n=%d , m=%d\n",n,m);fflush(stdout);
for(j=0;j<m;j++)
{
//printf("Innit i=%d j=%d\n",i,j);fflush(stdout);
k=fscanf(fp,"%d",&d);
if(k!=1){
j++;break;
}
//printf("fscan1 passed\n");fflush(stdout);
k=fscanf(fp,"%d",&e);
if(k!=1){
j++;break;
}
printf("fscanf2 passed\n");fflush(stdout);//prints
a[i][j]->s = d; //segfaults here
printf("dpassed\n");fflush(stdout); //doesnt print
a[i][j]->t = e;
//printf("dpassed\n");fflush(stdout);
if(j==m-1){
count++;
//printf("enter break\n");fflush(stdout);
}
count++;
//printf("out j a[%d][%d] = %d and %d k=%d\n",i,j,a[i] [j]->s,a[i][j]->t,k);fflush(stdout);
}
//printf("enter out i=%d\n",i);fflush(stdout);
}
//printf("brokenout");fflush(stdout);
if((k = fscanf(fp,"%lf",&d)) >0)
count++;
fclose(fp);
//check matrix sizes
if((i!=n) || j!=m-1 || count!=(n * m))
return -1;
}
return 1;
}
EDIT:
Disregard w and z
At run time I had this:
n=1 , m=3
Innit i=0 j=0
fscan1 passed
fscanf2 passed
a[0][0] = 0 and 0 k=1 w='' z=''
dpassed
dpassed
out j a[0][0] = 5 and 4 k=1
Innit i=0 j=1
fscan1 passed
fscanf2 passed
[1] 13367 segmentation fault
EDIT2:
Sorry I had posted code from 2 different projects. num_t is the typedef struct, I had issues editing my code when I pasted because of how putty copied my files
EDIT3:
Format and the finished product
#include "header.h"//contains struct
int read_matrix(int row, int col, num_t** a, char* file)
{
int i,j,k,count,d,e;
FILE *fp;
fp = fopen(file,"r");
//check if file opened
if(fp == NULL)
{
fclose(fp);
return -1;
}
else
{
i=0;
k=0;
count=0;
for(i=0;(k!=EOF)||i<row;i++)
{
for(j=0;j<col;j++)
{
k=fscanf(fp,"%d%d",&d,&e);
if(k!=2){
break;
}
a[i][j].s = d;
a[i][j].t = e;
if(j==col-1){
count++;
}
count++;
}
}
fclose(fp);
//check matrix sizes
if((i!=row) || j!=col-1 || count!=(row * col))
return -1;
}
return 1;
}
In main:
pb = matrix(m,x,a,*(argv+3));
Conclusion
2D struct arrays are not like 2D int arrays. Don't pass the address of a struct inside this type of function.

instead of
a[i][j]->s = s
a code like this will work.
p = a[i];
p[j].s = s;

You should have:
malloc(sizeof(num_t));
The pointer symbol will only give you 4 bytes, hence the memory fault.

When you call matrix(), you pass the address of a. If you think of num_t ** as a Matrix_t type, then you are passing a pointer to Matrix_t.
num_t **a;
...
pb = matrix(n,m,&a,*(argv+3));
And inside matrix():
int matrix(int n, int m, num_t ***a, char* file)
{
...
a[i][j]->s = d; //segfaults here
Here, when i becomes 1, you are trying to access the next Matrix_t, but you only passed a pointer to a single Matrix_t. In order to make this work, you have to dereference the pointer before you index the elements. Eg.:
(*a)[i][j].s = d; //segfaults here
Or, better yet: Pass a instead of &a, and change your function definition to use a double pointer instead of a triple pointer. Note that you also need to change your ->'s to .'s. There may be other changes that are necessary; I didn't look too far into your code.

Related

"segmentation fault" when assigning values to a specific position in a dynamically allocated matrix

I did this plenty of times but suddenly I can't get over this error. I've got a simple input.txt file with this structure:
3 4
2 1 1
1 2 3
8 3 3
Where the first line is basically the matrix's size and then follows value row col each line. I'm using calloc so the matrix is set to 0 and then reading the file I replace the values and their position. And exactly in the readFile() function i get "segmentation fault", I guess when it tries to replace the values in the matrix.
As a consequence what I'm trying to get is this:
2 0 0 0
0 0 1 0
0 0 8 0
void readSize(FILE *fp, int *rows, int *cols) {
fscanf(fp, "%d %d", rows, cols);
}
void readFile (FILE *fp, int **A) {
int val, row, col;
val = row = col = 0;
char buffer[100];
fgets(buffer, 100, fp); //* skip first line
while(!feof(fp)) {
fscanf(fp, "%d %d %d", &val, &row, &col);
A[row][col] = val;
val = row = col = 0;
}
}
int **allocMatrix(int m, int n) {
int **A = (int** )calloc(m, sizeof(int* ));
for( int i = 0; i < m; i++) *(A + i) = (int* )calloc(n, sizeof(int));
if (A == NULL) {
handleErr(ALLOC_ERR);
free(A);
}
return A;
}
int main() {
FILE *fp = fopen(INPUT, "r");
if (fp == NULL) handleErr(READ_FILE_ERR);
int **A, m, n; //! m -> rows | n -> cols
readSize(fp, &m, &n);
A = allocMatrix(m, n);
readFile(fp, A);
fclose(fp);
printMatrix(A, m, n);
return 0;
}
The code has several minor mistakes. The bug you are specifically looking for appears to be A[row][col] = val;. Since you've allocated a pointer table of size 3x4, you cannot access array item [3][3] in that array, since arrays are 0-indexed in C. Your input file appears to be 1-indexed.
One way to rewrite the code into using proper 2D arrays instead would be something like this:
readSize(fp, &m, &n);
int (*A)[n+1] = allocMatrix(m,n);
...
free(A);
With the function properly rewritten as:
void* allocMatrix(int m, int n)
{
int (*A)[n+1] = calloc( 1, sizeof(int[m+1][n+1]) );
if(A == NULL)
{
handleErr(ALLOC_ERR);;
}
return A;
}
You can rewrite the other functions to work with 2D arrays too, for example:
void readFile (FILE *fp, int x, int y, int A[x][y])
Then ideally check if the read row and cols are inside the bounds of x and y before accessing that location.
You should also check the result of fscanf instead of incorrectly using while(!feof(fp)). In case fscanf fail you currently still try to access the data read, which is wrong.

C string pointer initializes itself then de-initializes itself?

This is an excerpt from a Conway's Game of Life-program that I'm writing. In this part I'm trying to get the program to read a file that specifies what cells are to be populated at the start of the game (i.e. the seed).
I get a weird bug. In the read_line function, the program crashes online[i++] = ch statement. When I debug the program, I see that the line-pointer is NULL when it crashes. Fair enough, I think, I should initialize line. But here is the (for me) strange part:
The read_line function has already successfully execute twice and got me the first two lines (4\n and 3 6\n) from the seed file. And when I look at the execution in the debugger, I see that line is indeed holding a value in those first two executions of read_line. How is this possible? How can line be initialized without me initializing it and then suddenly not be initialized anymore?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define MAX_COORDINATE_SIZE 50
#define MAX_FILENAME_SIZE 20
#define MAX_GENERATIONS 10
#define MAX_REPETITION_PERIOD 4
struct coord{ //Holds coordinates to a cell
int x;
int y;
};
struct cell{
int pop; //Populated
int age;
};
struct coord *read_init(FILE *fp, int *i);
static int read_line(FILE *fp, char *line, int max_length);
struct coord read_coords(char *line);
struct cell **create_board(int x, int y);
struct cell **start_game(FILE *fp, int nrows, int ncols);
struct cell new_cell(int x, int y, int pop, int age);
void print_board(struct cell **board, int nrows, int ncols);
void populate_board(struct coord *coords, struct cell ***board, int *n);
int main(int argc, const char * argv[]) {
int gens;
char gens_string[MAX_GENERATIONS];
if(argc != 3){
fprintf(stderr, "Usage: %s <seed-file> <generations>\n<seed-file> can me up to %d characters long\n", argv[0], MAX_FILENAME_SIZE);
exit(1);
}
FILE *fp = fopen(argv[1], "r");
strncat(gens_string, argv[2], MAX_GENERATIONS);
gens = atoi(gens_string);
int nrows = 10;
int ncols = 10;
struct cell **board= start_game(fp, nrows, ncols);
print_board(board, nrows, ncols);
return 0;
}
struct coord *read_init(FILE *fp, int *n){ //Takes in filename and returns list of coordinates to be populated
char raw_n[100];
struct coord *coords;
char *line;
read_line(fp, raw_n, 100); // get the first line of the file (number of popuated cells)
*n = atoi(raw_n);//make an int out of raw_n
coords = malloc(sizeof(struct coord)*(*n)); //Allocate memory for each coord
for(int i = 0; i<(*n); i++){ // for each line in the file (each populated cell)
read_line(fp, line, MAX_COORDINATE_SIZE);
coords[i] = read_coords(line); //Put coordinates in coords
line = '\0';
}
return coords; // return coordinates
}
static int read_line ( FILE *fp, char *line, int max_length)
{
int i;
char ch;
/* initialize index to string character */
i = 0;
/* read to end of line, filling in characters in string up to its
maximum length, and ignoring the rest, if any */
for(;;)
{
/* read next character */
ch = fgetc(fp);
/* check for end of file error */
if ( ch == EOF )
return -1;
/* check for end of line */
if ( ch == '\n' )
{
/* terminate string and return */
line[i] = '\0';
return 0;
}
/* fill character in string if it is not already full*/
if ( i < max_length )
line[i++] = ch;
}
/* the program should never reach here */
return -1;
}
struct coord read_coords(char *line){ // Returns coordinates read from char *line
struct coord c;
char *x;
char *y;
x = malloc(sizeof(char)*MAX_COORDINATE_SIZE);
y = malloc(sizeof(char)*MAX_COORDINATE_SIZE);
int i = 0;
do{
x[i] = line[i]; //Get the x coordinate
i++;
}while(line[i] != ' ');
i++;
do{
y[i-2] = line[i];
i++;
}while(line[i] != '\0');
c.x = atoi(x)-1;
c.y = atoi(y)-1;
return c;
}
void init_board(int nrows, int ncols, struct cell ***board){
*board = malloc(nrows * sizeof(*board) + nrows * ncols * sizeof(**board));
//Now set the address of each row or whatever stackoverflow says
struct cell * const firstrow = *board + nrows;
for(int i = 0; i < nrows; i++)
{
(*board)[i] = firstrow + i * ncols;
}
for(int i = 0; i < nrows; i++){ //fill the entire board with pieces
for(int j = 0; j < ncols; j++){
(*board)[i][j] = new_cell(i, j, 0, 0);
}
}
}
void print_board(struct cell **board, int nrows, int ncols){
printf("--------------------\n");
for(int i = 0; i<nrows; i++){
for(int j = 0; j<ncols; j++){
if(board[i][j].pop == 1){
printf("%d ", board[i][j].age);
}else if(board[i][j].pop == 0){
printf(" ");
}else{
printf("\n\nERROR!");
exit(0);
}
}
printf("\n");
}
printf("--------------------");
printf("\n");
}
struct cell **start_game(FILE *fp, int nrows, int ncols){ //x,y are no of rows/columns, fn is filename
int n; // n is the number of populated cells specified in the seed
struct coord *coords = read_init(fp, &n); // get the list of coords to populate board with
struct cell **board;
init_board(nrows, ncols, &board); // Set up the board
populate_board(coords, &board, &n); //populate the cells specified in the seed
return board;
}
void populate_board(struct coord *coords, struct cell ***board, int *n){
for(int i = 0; i < *n; i++){
(*board)[coords[i].x][coords[i].y].pop = 1; //populate the cell
}
}
struct cell new_cell(int x, int y, int pop, int age){ //Return new populated or non-populated cell with specified coordinates
struct cell c;
c.pop = pop;
c.age = age;
return c;
}
The seed file:
4
3 6
4 6
5 6
5 7
EDIT:
The error message: Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
I shall add that if I add a line line = malloc(sizeof(char)*MAX_COORDINATE_SIZE+1) after the declaration of line in read_init, I still get the same error.
In read_init() :
struct coord *read_init(FILE *fp, int *n){
//...
char *line;
//...
for(int i = 0; i<(*n); i++) {
read_line(fp, line, MAX_COORDINATE_SIZE);
coords[i] = read_coords(line); //Put coordinates in coords
line = '\0'; // <<--- you set line to NULL here.
*line = 0; // this is what you wanted to do, is not necessary...
}
// ....
}
I get a weird bug.
I suggest asking some questions about the compiler output. We should never blindly ignore warnings, after all. Speaking of reading things, I think you're spending too long reading StackOverflow and not long enough reading K&R2e and doing the exercises. We'll come back to that.
In the read_line function, the program crashes on line[i++] = ch statement ... But here is the (for me) strange part: ... The read_line function has already successfully execute twice and got me the first two lines (4\n and 3 6\n) from the seed file
The C and C++ standards rationalise the concept of "undefined behaviour" for this class of errors that are computationally difficult to diagnose. In other words, because you made an error, the behaviour of your program is undefined. It isn't required that your malfunctioning code crash every time, as that would be defining the undefined; instead they leave this "undefined" and the first two times your erroneously code works (whatever that means), purely by coincidence that the uninitialised variable points somewhere accessible. Later on you assign line = '\0';, which changes line to be a null pointer, and then you try to assign into whatever that null pointer points at. That's more undefined behaviour.
How is this possible? How can line be initialized without me initializing it and then suddenly not be initialized anymore?
line isn't initialised; you're using it uninitialised, which happens to coincidentally work (but needs fixing), then you assign it to be a null pointer and dereference a null pointer (more UB that needs fixing). Such is the nature of undefined behaviour. Such is the nature of learning C by guessing. You need a book!
I shall add that if I add a line line = malloc(sizeof(char)*MAX_COORDINATE_SIZE+1) after the declaration of line in read_init, I still get the same error.
You need to fix all of the errors, not just the one. For assistance you could see the warnings/errors your compiler emits. I see more uninitialised access here:
char gens_string[MAX_GENERATIONS]; // <--- where's the initialisation??
// Snip
strncat(gens_string, argv[2], MAX_GENERATIONS); // Boom
There's some really sus code around this comment: //Now set the address of each row or whatever stackoverflow says ... and on that note I want to point out that there are some subtly toxic know-it-alls who answer questions despite having as many misunderstandings as you, a humble person, and so you shouldn't hope to get the same quality of education from StackOverflow as you would from K&R2e... but apparently I'd be toxic for pointing out the egomaniacs and suggesting decent resources to learn from, so that's none of my business 🙄🤷‍♂️ let's just let the sociopaths sabotage the education of everyone huh?
(*board)[i] = firstrow + i * ncols;
Look, there is no guarantee that this even compiles let alone that the address on the right has a suitable alignment to store the type of value on the left. Misaligned access causes more undefined behaviour, which may also work coincidentally rather than logically. Just as you've never seen alignment violations before, so too has the person who suggested you use this code. Assuming the alignment requirements for your implementation are satisfied by this code, we then have the same questions to raise here:
(*board)[i][j] = new_cell(i, j, 0, 0);
Your whole program needs remodelling around the declaration of board changing from struct cell **board to struct cell (*board)[ncols];, for example. It'll become much simpler, and a whole class of bugs related to alignment requirements will disappear. To see the extent of the simplification, here's what your init_board ought to look like:
void init_board(int nrows, int ncols, struct cell (**board)[ncols]){
*board = malloc(nrows * sizeof(*board));
// NOTE: I snipped the erroneous StackOverflow logic around the comment mentioned above; you don't need that crud because of the more suitable choice of type
for(int i = 0; i < nrows; i++){ //fill the entire board with pieces
for(int j = 0; j < ncols; j++){
(*board)[i][j] = (struct cell){ 0, 0 };
}
}
}

Pointer values changes when using realloc() on pointer to pointer

I have to read from a file which has a unknown number of students records in it written in binary, then sort the students by their GPA and send to stdout.
Our sort function had to be like
void insertion_sort(Student **, int);
That's why I choose to use an pointer to a pointer to Student (probably not the best solution? I think I could have just sent an pointer to Student like this (&p_to_Student, n) ?)
The code is bellow, the problem is that when I print the first element of what p is pointing to (the first students name) I get gibberish, the other students are fine.
I checked the value of p, and it does change after realloc() is called, and because it's also the address of the first element of p (right?).
Also checked with Valgrind and it returns a bunch of errors about memory leaks!
The code runs fine when there is no realloc() call, also when I initialize p after I'm done reading the file. So it must be something to do with not using realloc() correctly.
Bonus question: is this a proper way to read an unknown number of data entries from a file?
#include <stdio.h>
#include <stdlib.h>
struct student {
char name[30];
char surname[30];
double GPA;
};
typedef struct student Student;
void insertion_sort(Student **arr, int n)
{
int i,j;
for (i=1; i<n; i++)
{
Student *tmp = arr[i];
for (j=i; j>0 && (tmp->GPA > arr[j-1]->GPA); j--)
arr[j] = arr[j-1];
arr[j] = tmp;
}
}
int main(int argc, char **argv)
{
FILE *in;
Student s, *arr, **p;
size_t ret;
int i = 1, n=0, c=2;
in = fopen(argv[1], "rb");
if (in == NULL)
return printf("Can't open file!\n"), 1;
arr = (Student*) malloc(c*sizeof(Student*));
p = (Student**) malloc(c*sizeof(Student*));
do
{
ret = fread(&s, sizeof(Student), 1, in);
if (ret)
{
if (n == c)
{
arr = (Student*) realloc(arr, (c*=2)*sizeof(Student));
p = (Student**) realloc(p, c*sizeof(Student*));
}
// when I print the value of pointer p
// the values is changed when realloc() is called
printf("p = %p\n", p);
arr[n] = s;
p[n] = arr+n;
n++;
}
} while (ret);
fclose(in);
// If I do this instead the program runs correctly
//p = (Student**) malloc(c*sizeof(Student));
//for (int i=0; i<n; i++)
//{
//p[i] = arr+i;
//}
insertion_sort(p, n);
for (i=0; i<n; i++)
{
printf("%2d. %-20s %-20s %7.2lf\n", i+1, p[i]->name,
p[i]->surname, p[i]->GPA);
}
free(arr);
free(p);
return 0;
}
realloc may change the pointer. That means all pointers into that pointer may become invalid. In your case, p holds pointers into arr.
Your problem is not that the value of p changes, but that the old values of p are no longer valid when the value of arr changes.
To illustrate (all pointer and size values are made up):
sizeof(stud) == 16;
allocate arr: arr == 0x00100000;
1st value: arr[0] = stud1; p[0] = &arr[0]; // 0x00100000
2nd value: arr[1] = stud2; p[1] = &arr[1]; // 0x00100010
reallocate arr: arr == 0x00200000;
old address of arr is no longer valid!
3rd value: arr[0] = stud1; p[2] = &arr[2]; // 0x00200020
Now your pointer array looks like this:
p[0] == 0x00100000 // no longer valid!
p[0] == 0x00100010 // no longer valid!
p[0] == 0x00200020 // okay
Because you need p only for your sorting, the approach you have commented out – to allocate p at one go before sorting – is better.
realloc is useful only if you don't now beforehand how big your array is, so you should use it as long as you are building the array. When you are done building the array and you can be sure that arr will stay the same you should create the array of pointers, p.

Put array as argument and read its value

I am scanning for values using function .
int **array(int * counter) {
int **vrat;
int max = 5;
int index = 0;
int i;
vrat = malloc(max*sizeof(int*));
for ( i = 0; i < max ; i++) {
vrat[i] = malloc(2 * sizeof(int));
}
int x;
int y;
char c;
while (scanf("%d%c%d", &x, &c, &y) != EOF) {
vrat[index][0] = x;
vrat[index][1] = y;
index++;
}
*counter = index;
return vrat;
}
and calling it in main to return the array, which works .
int main()
{
int counter=0;
int **mej;
int gg;
mej = array(&counter);
int i;
gg = pocet(mej, &counter);
return 0;
}
what is bothering my mnd is "pocet" function , i am passing an array in it and want to print its value . but it always print undefined numbers
Function looks like this
int pocet(int array[][2],int *counter) {
int poc = 0;
int i;
for ( i =0; i < *counter ;i++) {
printf("cislo = %d", array[i][0]);
}
return poc;
}
as you can see , it has static 2nd dimension , how can i make this work?
You are allocating space for 5 pointers, you should multiply by the size of a pointer and not the size of an int, like this
vrat = malloc(max * sizeof(int *));
/* ^ pointer */
Although you can completely avoid the mistake by multiplying by the size of the pointer type like this
vrat = malloc(max * sizeof(*vrat));
and ALWAYS check that malloc() has not returned NULL before actually using the pointer.
Also, don't compare scanf() to EOF since it's very unlikely to get an EOF before an input error because it requires explicit input from the user, instead do this
while(scanf("%d%c%d", &x, &c, &y) == 3)
The return type of your function should match that of the returned object, in this case int **, change the function signature to
int **array(int *content)
vrat = malloc(max*sizeof(int*));
How do you know whether the memory successfully got allocated or not?
Always check the pointer returned by malloc & family functions for equivalence with NULL to avoid possible SegFault.
while (scanf("%d%c%d", &x, &c, &y) != EOF)
What if there's matching failure for c? Then scanf will return 1 and while will still go for iteration even if scanf could not store values in c and y.
So always compare scanf return value with no. of arguments instead of EOF
while (scanf("%d%c%d", &x, &c, &y) != EOF) {
vrat[index][0] = x;
vrat[index][1] = y;
index++;
}
Here what if index >= max?
Since you have allocated memory for only max integer pointers you must not try to access the memory beyond the allocated chunk.
Solution: Change while condition to
while ((scanf("%d%c%d", &x, &c, &y) == 3) && (index < max))
So the correct code snippet would be:
vrat = malloc(max*sizeof(int*));
if(!vrat)
{
printf("vrat: malloc failed!\n");
exit(1);
}
for ( i = 0; i < max ; i++) {
vrat[i] = malloc(2 * sizeof(int));
if(!vrat[i])
{
printf("vrat[%d]: malloc failed!\n", i);
exit(1);
}
}
int x;
int y;
char c;
while ((scanf("%d%c%d", &x, &c, &y) == 3) && (index < max)) {
vrat[index][0] = x;
vrat[index][1] = y;
index++;
}
An int** is not an int[][2]. The first is a pointer to pointers to int while the second (as an argument) is a pointer to int[2]. You cannot convert between the two the way you tried. You should have gotten a compiler warning/error about this.
The easiest way to fix this is to have pocet take an int** as the first argument. Fix the issues others have mentioned as well.
You have defined int **vrat;
When you do malloc, you need to use int ** or int * and not int

C pointer arithmetic palindrome

I'm a java student who's currently learning about pointers and C.
I tried to make a simple palindrome tester in C using a single array and pointer arithmetic.
I got it to work without a loop (example for an array of size 10 :*(test) == *(test+9) was true.
Having trouble with my loop. School me!
#include<stdio.h>
//function declaration
//int palindrome(int *test);
int main()
{
int output;
int numArray[10] = {0,2,3,4,1,1,4,3,2,0};
int *ptr;
ptr = &numArray[0];
output = palindrome(ptr);
printf("%d", output);
}
//function determine if string is a palindrome
int palindrome(int *test) {
int i;
for (i = 0; i <= (sizeof(test) / 2); i++) {
if (*(test + i) == *(test + (sizeof(test) - i)))
return 1;
else
return 0;
}
}
The Name of the array will itself acts as a pointer to an first element of the array, if you loose the pointer then there is no means for you to access the element of the array and hence you can send just the name of the array as a parameter to the function.
In the palindrome function:
you have used sizeof(test)/2. what happens is the address gets divided which is meaningless and hence you should not use that to calculate the mid element.
sizeof the pointer will be the same irrespective of the type of address that gets stored.
Why do you copy your pointer in another variable?
int *ptr;
ptr = &numArray[0];
Just send it to you function:
palindrome(numArray);
And sizeof(test) give you the memory size of a pointer, it's not what you want. You have to give the size in parameter of your function.
int palindrome(int *test, int size){
...
}
Finally your code must look like this:
#include<stdio.h>
int palindrome(int *test, int size);
int main()
{
int output;
int numArray[10] = {0,2,3,4,1,1,4,3,2,0};
output = palindrome(numArray, 10);
printf("%d", output);
}
//function determine if string is a palindrome
int palindrome(int *test, int size) {
int i;
for (i = 0; i < size / 2; i++) {
if (*(test + i) != *(test + (size - 1) - i))
return 0;
}
return 1;
}

Resources