C - initialized pointer throws exception about nullptr - c

I have a code that intends to find minimal value using pointers, using a function.
The problem is that even though I initialize the pointer while debugging it shows:
Exception thrown: read access violation.
min was nullptr.
At line 37. The code can be seen below:
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
int tab_min(const int* tab, int size, int *min);
int main()
{
int limit;
int tab[100];
int * ptab = tab;
int min = 2;
int *pmin = &min;
printf("Number of elements: ");
scanf("%d", &limit);
printf("List the elements \n");
for (int i = 0; i < limit; i++)
{
scanf("%d", &*(ptab + i));
}
tab_min(ptab, limit, pmin);
return 0;
}
int tab_min(const int* tab, int size, int *min)
{
if ((tab == NULL) || (size <= 0) || (min = NULL))
{
return 0;
}
else
{
for (int i = 0; i < size; i++)
{
if (*(tab + i) < *min) *min = *(tab + i); //Exception is here
}
return 0;
}
}
Can somebody please explain to me what is wrong with my reasoning?

The critical error is that if ((tab == NULL) || (size <= 0) || (min = NULL)) assign var min to NULL.
if you need to record the minimum value, you can use pointer address as parameter
int tab_min(const int* tab, int size, int **min);
and
if (*(tab + i) < **min) *min = (tab + i);
and call like
tab_min(ptab, limit, &pmin);
Thanks #Gerhardh for pointing out my mistake

Related

Printf function who returning an array of int

I'm trying this exercice but I don't know how to printf my function in main.
Exercice:
1) Write a function who returning an int tab with all values between min and max
#include <stdlib.h>
#include <stdio.h>
int *ft_range(int min, int max)
{
int len;
int *tab;
len = min;
while (len < max)
len++;
tab = (int *)malloc(sizeof(*tab) * len + 1);
while (min < max)
{
*tab = min;
min++;
}
return(tab);
}
int main()
{
ft_range(0, 10);
return(0);
}
returning an int tab with all values between min and max
Depending on the idea of "between", it is an open question if the end values should be included. Given OP's mis-coded +1 in sizeof(*tab) * len + 1, I'll go with the idea both ends should be included.
Miscalculation of len
Rather than loop, simply subtract
//len = min;
//while (len < max)
// len++;
len = max - min + 1;
Allocation miscalculated
Good to use sizeof *pointer, yet the + 1 makes little sense. If anything the ... * len + 1 should have been ... * (len + 1). Yet the +1 is handled with the above fix. Also cast not needed in C.
// tab = (int *)malloc(sizeof(*tab) * len + 1);
tab = malloc(sizeof *tab * len);
Wrong assignment
Code repeatedly assigned the same *tab location.
//while (min < max)
//{
// *tab = min;
// min++;
//}
for (int i = min; i <= max; i++) {
tab[i - min] = i;
}
No allocation error checking nor min, max validation
Potential for int overflow with mix - min
Be sure to free allocations
Alternative
#include <stdlib.h>
#include <stdio.h>
int *ft_range(int min, int max) {
if (min > max) {
return NULL;
}
size_t len = (size_t)max - min + 1;
int *tab = malloc(sizeof *tab * len);
if (tab == NULL) {
return NULL;
}
for (size_t i = 0; i < len; i++) {
tab[i] = int(min + i);
}
return tab;
}
int main() {
int mn = 0;
int mx = 10;
int *ft = ft_range(mn, mx);
if (ft) {
int *p = ft;
for (int i = mn; i <= mx; i++) {
printf("%d ", *p++);
}
free(ft);
}
return 0;
}
inside "ft_range", when you are trying to calculate the length the array needs to do, all you have to do is subtract the minimum from the maximum. what you did is much slower and unnecessary.
when allocating memory, you did not need to add a "+1" at the end. you may have seen it done in other examples, but it does not apply here.
the "while" loop inside "ft_range" needs to have a "<=" sign, otherwise it will stop before it reaches the "max" value.
when adding a value to the "tab" int array, you are always doing so by dereferencing it (putting a "*" before it), so every one of your values will come on the first position of the array and overwrite themselves. you need to have another "int i" to keep track of the current index of the array.
make sure to free the memory you allocated with "malloc" after you finish your enumeration. it does not matter right now, but if you ever get to writing more complex programs you will need to do so to keep the performance up, which can be critical.
here's a working code, with a few comments (i'm shit at comments, if you don't understand them, just ask me bro)
#include <stdlib.h>
#include <stdio.h>
int *ft_range(int min, int max)
{
int len;
int * tab;
len = max-min;
tab = (int *)malloc(sizeof(*tab) * len);
// create an index to track the position inside "tab"
int i = 0;
// sign needs to be "<=" so it does not stop before it reaches the max value
while (min <= max)
{
tab[i] = min;
// ++ needs to come before so the variable's value is updated right here
++min;
// increase the i index to the next position in "tab"
++i;
}
return(tab);
}
int main()
{
int min = 5;
int max = 10;
int len = max-min;
int * range = ft_range(min, max);
for(int i = 0; i <= len; ++i)
{
// %d = integer
// \n = move to next line
printf("%d\n", range[i]);
}
getchar();
return(0);
}
You correctly allocate memory to the table, you just need to printf the value in your main by using a loop trough your tab, i write this code who work perfectly.
#include <stdlib.h>
int *ft_range(int min, int max)
{
int *ptr;
int mi;
int i;
int range;
range = (max - min);
mi = min;
ptr = NULL;
if (min > max)
return (NULL);
else
ptr = malloc(sizeof(int) * range);
i = 0;
while (i < range)
{
ptr[i] = mi + i;
i++;
}
return (ptr);
}
// #include <stdio.h>
// int main()
// {
// //int i = 0;
// int min = 1;
// int max = 30;
// while(min < max)
// {
// printf("%d\n", *ft_range(min, max));
// min++;
// }
// }

variable sized object may not be initialized

I am getting the error variable sized object may not be initialized and I don't understand why.
Could someone show me how to fix this line?
int arr[size] = (int *)(augs->one);
Here is my code:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
int count = 0;
int cmpfunc(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
struct structure {
int two;
int *one;
};
void *sort(void *augments) {
struct structure *augs = (struct structure*)augments;
int i = 0;
int size = 1;
size = augs->two;
int arr[size] = (int *)(augs->one);
//int *arr = (int *)data;
//printf("sizeof:%d\n", sizeof(arr));
qsort(arr, size, sizeof(int), cmpfunc);
printf("finaloutput:\n");
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return NULL;
}
int main(int argc, char *argv[]) {
FILE *myFile;
myFile = fopen("data.txt", "r");
// number of lines in file
char charicter;
for (charicter = getc(myFile); charicter != EOF; charicter = getc(myFile)) {
if (charicter == '\n') {
count++;
}
}
printf("count is %d\n", count);
int numberArray[count];
int i = 0;
if ((myFile = fopen("data.txt", "r"))) {
while ((fscanf(myFile, "%d", &numberArray[i]) != EOF)) {
++i;
}
fclose(myFile);
}
assert(argv[1] != NULL);
int num = atoi(argv[1]); //num equals number input
int arrayarray[num - 1][(count / num)];
int idx;
for (i = 0; i < (count); i++) {
printf("numberarray[%d]= %d\n", i, numberArray[i] /*[0],numberArray[i][1]*/);
}
for (i = 1; i < num + 1; i++) {
for (idx = 0; idx < (count / num); idx++) {
arrayarray[i - 1][idx] = numberArray[i * idx];
}
}
///*
for (i = 0; i < ((count / num)); i++) {
printf("arrayarray[0]=%d\n", arrayarray[0][i]);
}
//*/
int lastarray[((count / num) + (count % num))];
for (idx = 0; idx < ((count / num) + (count % num)); idx++) {
lastarray[idx] = numberArray[idx + ((count / num) * (num - 1))];
}
for (i = 0; i < ((((count / num) + (count % num)))); i++) {
printf("lastaray[%d]=%d\n", i, lastarray[i]);
}
//*******************
pthread_t thread_id_arr[num];
for (i = 0; i < num; i++) {
pthread_t tid;
struct structure *augs;
if (i != (num - 1)) {
augs = malloc(sizeof(struct structure) + sizeof(int) + sizeof(int) * num);
(*augs).one = arrayarray[i];
(*augs).two = (count / num);
pthread_create(&tid, NULL, sort, augs);
} else {
(*augs).one = lastarray;
(*augs).two = (count / num) + (count % num);
pthread_create(&tid, NULL, sort, augs);
//pthread_create(&tid, NULL, sort, (void*)lastarray);
}
thread_id_arr[i] = tid;
}
for (i = 0; i < num; i++) {
pthread_join(thread_id_arr[i], NULL);
}
return 0;
}
As others pointed out, you can't initialize a Variable Length Array with a pointer, like you are doing. However, you don't actually need a VLA at all. Use this instead :
int *arr = augs -> one;
You want to act directly on the array that is passed into the thread, not make a copy of it.
That being said, I see another problem. In the loop that spawns the sorting threads, you are not allocating a new args on the last loop iteration, it reuses the allocated args from the previous iteration, which can cause disaster for the 2nd-to-last thread. You need to move the malloc() call above the if.
Also, the malloc() is allocating more memory than your threads actually use. You only need to allocate enough memory for just the struct by itself, not for any integers following the struct.
Also, when each thread is done using the allocated args that it is given, it needs to free() the args to avoid leaking memory.

Realloc an array of double

The exercise, that I have to complete says:
That array_remove function must remove from the array arr the value, that is in the position pos, and scale of a position successive values of pos, and eventually change the array size for no gaps.
If this value is not included in the array (if pos is greater than pn (array size)), then you should not do anything.
My problem is:
Probably very wrong to use the malloc function, because when it is performed, it shows the following error:
MAIN.C:
#include "array.h"
int main(void)
{
double arr[] = { 1.0,2.0,3.0,4.0,5.0 };
size_t pn = 5;/*array length*/
size_t pos = 2;/*position of the number to be deleted*/
array_remove(arr, &pn, pos);
}
ARRAY.C:
#include "array.h"
void array_remove(double *arr, size_t *pn, size_t pos)
{
int x = *pn;
int y = pos;
if (x > y)
{
for (int i = y; i < x; i++)
{
arr[i] = arr[i + 1];
}
realloc(&arr, sizeof(double) * 4);
}
}
According to the C docs:
realloc Reallocates the given area of memory that must be previously allocated
by malloc(), calloc() or realloc() and not yet freed with free,
otherwise, the results are undefined.
You have an out of bound problem as well at the following lines when i=x-1 you try to access at arr[i+1] = arr[x=pn]:
for (int i = y; i < ; i++) {
arr[i] = arr[i + 1];
Check the following code out *(live: https://ideone.com/mbSzjL
#include<stdlib.h>
void array_remove(double **arr, int *pn, int pos) {
int x = *pn;
int y = pos;
if (x > y) {
//check if after deletion size is zero!
if (x > y) {
for (int i = y; i < x-1; i++) {
(*arr)[i] = (*arr)[i + 1];
}
*arr=realloc(*arr, sizeof(double) * x-1);
*pn=*pn-1;
}
}
}
int main(void) {
int pn = 20;/*array length*/
int pos = 5;/*position of the number to be deleted*/
double *arr = malloc(sizeof(double)*pn);
printf("%p\n",arr);
for(int i=0;i<pn;i++){
arr[i] = i;
}
for(int i=0;i<pn;i++){
printf("%.f ",arr[i]);
}
printf("\n");
printf("%i\n",pn);
array_remove(&arr, &pn, pos);
printf("%p\n",arr);
for(int i=0;i<pn;i++){
printf("%.f ",arr[i]);
}
printf("\n");
printf("%i",pn);
free(arr);
}
Don't forget to realloc using the right size (not using an hardcoded 4) and check for the edge case in which size is zero after deletion!
In addition,
free the memory at the end and to update the size variable.
http://en.cppreference.com/w/c/memory/realloc
arr array is stack allocated. You cannot realloc something that wasn't mallocated.
You probably want something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
bool array_remove(double **arr, size_t *pn, size_t pos)
{
int x = *pn - 1;
int y = pos;
int i;
double *temp;
if (x > y) {
for (i = y; i < x; i++) {
(*arr)[i] = (*arr)[i + 1];
}
temp = realloc(*arr, sizeof(double) * x);
}
if (arr != NULL)
{
*arr = temp;
*pn -=1;
return true;
}
else
{
return false;
}
}
int main(void)
{
size_t pn = 5; // array length
size_t pos = 2; // position of the number to be deleted
int i;
double *arr = malloc(pn*sizeof(double));
if (arr != NULL)
{
for (i=0; i<pn; i++)
{
arr[i] = (double)(i+1);
}
if (array_remove(&arr, &pn, pos) == false)
{
printf("Failed to remove element %zu\n", pos);
}
for (i=0; i<pn; i++)
printf ("arr[%d]: %f\n", i, arr[i]);
free(arr);
}
else
{
printf("Failed to alloc array\n");
}
return 0;
}
As you can see I changed the loop of array_remove. In your code you are addressing the array out of bound on the last loop, because of i=4 and then:
arr[i] = arr[i + 1]; is arr[4] = arr[5]
Indexes of a 5 elements array start from 0 to 4.
actually you have a different problem here:
int x = *pn; //x=5
int y = pos; //y=2
if (x > y) {
for (int i = y; i < x; i++) {
arr[i] = arr[i + 1];
}
On the last iteration, you do
arr[4] = arr[5]
This is out of range addressig and that's probably your problem, or at least your first one.
Also, even though it's not technically wrong it's conceptually wrong:
array_remove(arr, &pn, pos);
Never pass a value by pointer unless you plan on modifying it. Not the case here, so you can pass it by value.

Dynamic Program in C

Hi Guys i have edited the questions.Here is my entire code.I have given basic amount of readability to my program.I hope u guys can understand the program.
#include<stdio.h>
#include<stdlib.h>
int Max_Min(int,int,int,int *, int *);
int *Max,Number;
int main()
{
int n1, n2,Maximum_Element=0,*Max;
int i = 0, j = 0;
scanf("%d",&Number);
Max =(int *) malloc(sizeof(int)*Number);//Array Max is created
for (int k = 0;k <(Number/2);k++)
{
scanf("%d", &n1);
scanf("%d", &n2);
Max[k] = Max_Min(0,1,0,&n1,&n2);//Passing integer elements n1,n2 with flag 0
}
Maximum_Element=Max_Min(1,1,((sizeof(Max)*Number)/8),Max,Min);//Passing array elements Max,Min with flag 1 to function Max_Min
printf("Maximum_Element=%d", Maximum_Element);
return 0;
}
int Max_Min(int flag,int Max_Min_flag,int length,int *n1,int *n2)//n1 and n2 should be able to handle array and integers
{
int i=0,j = 0,k1,k2,Min1 = 0, Min2 = 0,count=0, Not_Zero = 0,x=0,y=0, *New_Max = 0,*New_Min;
/*Recursive Loop for splitting the array elements and calling the array */
if (flag == 1)
{
New_Max = (int *)(malloc(sizeof(int)*length));
for (;i <= ((length) / 2);i = i + 2)//
{
k1 = n1[i];
j = i + 1;
if (j <= ((length + 1) / 2))
{
k2 = n1[j];
New_Max[count] = Max_Min(0, 1, 0, &k1, &k2);//It is passing integer elements with flag 0 to function Max_Min
count++;
}
}
New_Max[count] = n1[j + 1];
for (int i = 0;i < count + 1;i++)
{
**/* Problem is assigning Max[i]=New_Max[i] is not getting assigned*/**
Max[i] = New_Max[i];//Copying from New_Max to Max because New_Max will be overwritten,so possible chaunce of dataloss
Not_Zero++;
}
while ((sizeof(Max) / 4 - (Not_Zero))>0)
{
Max[Not_Zero] = 0;
Not_Zero++;
}
/*Logic for calling recursive functions based on the count*/
if (count > 1)
{
count--;
Max_Min(1, 1, count, Max, Min);//Calling Recursive function by Passing Entire Arrays with flag 1.
}
else if (count == 1 && Max[1] == 0)
{
*n1 = Max[0];
*n2 = Min[0];
}
else if (count == 1 && Max[2] == 0)
{
Max_Min(1, 1, count + 1, Max, Min);
count--;
}
}
/*Logic for Finding Maximum & Minimum element is present down*/
if (flag == 0)
{
printf("flag");
if (Max_Min_flag == 1)
{
if (*n1 > *n2)
{
}
else if ((*n1 < *n2) && Max_Min_flag == 1)
{
int temp = 0;
temp = *n1;//5
*n1 = *n2;//7
*n2 = temp;//5
}
}
else if (Max_Min_flag == 2)
{
if (*n1 > *n2)//7>2
{
int temp = 0;
temp = *n1;//2
*n1 = *n2;//2
*n2 = temp;//2,7
}
else if (*n1 < *n2)
{
}
}
}
return *n1;//7
}
Problem is assigning Max[i]=New_Max[i] in function Max_Min().It shows Run time error as "Access violation writing location 0x00000000."
First you need to #include <stdlib.h> to use malloc
You must declare your function before using it.
func must return int*.
Also in func "n", first "Max", and second "Max" needs to be the same variable. Rename "n" to "Max"
This is the code corrected with an extra printf;
#include <stdio.h>
#include <stdlib.h>
int *Max,Number=5;
int* func(int *Max)
{
for(int j=0;j<5;j++)
Max[j]=j;//Its not working in this line
return Max;
}
int main()
{
Max=(int *) malloc(sizeof(int)*Number);
for(int i=0;i<5;i++)
Max[i]=i;
int* x = func(Max);
for(int i=0;i<5;i++)
printf("%d", x[i]);
}
The following contains only minor adaptations of your code and it runs fine:
int *func(int *n);
int *Max,Number=5;
int main()
{
int *x,i;
Max=(int *) malloc(sizeof(int)*Number);
for(i=0;i<Number;i++)
Max[i]=i;
x=func(Max);
free(Max);
return(0);
}
int *func(int *n)
{
int j;
for (j=0;j<Number;j++)
n[j]=Number-j; // reverse the number, just to check
return Max;
}

Array value getting changed

So I have two problems:
I'm using netbeans to code this.
The first is that the array value that I am setting in c.sArr is getting changed from 7 to some random number, and I can't figure out why.
The second is that when I try to run debug in netbeans, the code gives me a segfault, whereas when i run it normally it doesn't. It gives a segfault at the atoi function.
Whats going on here?
#include <stdio.h>
#include <stdlib.h>
#include "spoonMatrix.c"
int main(int argc, char** argv) {
int iterations;
int argCounter = 0;
int debug = 1;
int i,j,q;
if(argc < 2)
return -1;
if(debug == 1){
for(q=0;q<argc;q++)
printf("%s\n", argv[argCounter++]); //Checking the params
}
argCounter = 1;
iterations = atoi(argv[argCounter++]);
if(debug == 1)
printf("%d", iterations);
for(i=0;i<iterations;i++){
int rows = 0;
int columns = 0;
int m = 0, n, p, elemCount;
int posCount = 0;
int temp;
cm c;
c.row = rows;
c.column = columns;
c.elems = (char*)calloc(rows*columns, sizeof(char));
c.sArr = (int*)calloc(rows*columns, sizeof(int));
rows = atoi(argv[argCounter++]);
columns = atoi(argv[argCounter++]);
for(m=0;m<rows*columns;m++)
{
c.sArr[m] = -2;
//printf("Here");
}
if(debug == 1)
{
printf("Rows : Columns - %d : %d\n", rows, columns);
}
temp = argCounter;
printf("argCounter is: %d\n", argCounter);
for(elemCount = 0 ; argCounter < temp + rows; argCounter++)
{
for(n=0; n<columns; n++, elemCount++)
{
c.elems[elemCount] = argv[argCounter][n];
//if(debug == 1)
// printf("%c\t", c.elems[elemCount]);
if(c.elems[elemCount]== 's' || c.elems[elemCount] == 'S')
{
c.sArr[posCount] = elemCount;
printf("%c\t%d\t%d\t%d\n", c.elems[elemCount], elemCount, c.sArr[posCount++], posCount);
}
}
}
printf("%d\n", c.sArr[0]);
if(debug == 1)
{
for(j=0; j<rows*columns; j++)
{
printf("%c ", c.elems[j]);
}
printf("\n");
for(j=0;j<rows*columns;j++)
{
printf("%d ", c.sArr[j]);
}
}
}
return (EXIT_SUCCESS);
}
and
the other file is:
struct charMat{
int row;
int column;
char* elems;
int* sArr;
};
typedef struct charMat cm;
Coded in the hurry, excuse the weird debugging statements.
Thanks
You aren't allocating (enough) memory:
int rows = 0;
int columns = 0;
c.elems = (char*)calloc(rows*columns, sizeof(char)); // rows * columns is 0
c.sArr = (int*)calloc(rows*columns, sizeof(int)); // rows * columns is 0
rows = atoi(argv[argCounter++]);
columns = atoi(argv[argCounter++]);
From calloc:
If the size of the space requested is 0, the behavior is
implementation-defined: the value returned shall be either a null
pointer or a unique pointer.

Resources