Dynamic array of int pointers causing segmentation fault - c

I found a segmentation fault in my C code and could not find a good explanation or solution for it after searching.
This first code gives me segmentation fault after printing 0.
#include <stdlib.h>
#include <stdio.h>
int main() {
int **defs = malloc(16 * sizeof *defs);
int i;
for (i = 0; i < 16; i++) {
printf("%d\n", i);
*defs[i] = i;
}
free(defs);
return 0;
}
This second code works fine.
#include <stdlib.h>
#include <stdio.h>
int main() {
int *defs = malloc(16 * sizeof defs);
int i;
for (i = 0; i < 16; i++) {
printf("%d\n", i);
defs[i] = i;
}
free(defs);
return 0;
}
These are just examples, not my actual code. I also tried doing pointer arithmetic but same result.
Could someone please explain this? Thank you.

In first code you have not allocated each of the int* memory blocks.
So, before assigning values to defs[i], you have to populate it with memory of type int*.
defs[i] = (int*)malloc(sizeof(int) * number_of_elements);
And then defs[i][some_index] = value.

Related

Is there a way to initialize all int array elements to zero except for loop

Is there a way to initialize all int array elements to zero except a for loop where we loop through to set values to zero. Here the size of array is decided by input of user.
#include <stdio.h>
int main() {
int num_cases = 0;
scanf("%d", & num_cases);
int arr_counter[num_cases];
for (int x = 0; x < num_cases; x++) {
arr_counter[x] = 0;
}
}
Yes, you can do that in multiple ways under C standard. For example:
memset() [Stack and Heap]
calloc() [Heap Only]
loops, e.g., do-while, while and for [Stack and Heap]
{ } [Stack Only]
1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int arr[10];
size_t len_arr = sizeof(arr) / sizeof(*arr);
memset(arr, 0, sizeof(arr));
for(size_t i = 0; i < len_arr; i++)
printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
Note: We can use memset() to set all values as 0 or -1 for integral data types also. It will not work if we use it to set as other values. The reason is simple, memset() works byte by byte.
2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int *arr = calloc(10, sizeof(int));
if(!arr)
{
fprintf(stderr, "bad ptr");
return EXIT_FAILURE;
}
for(size_t i = 0; i < 10; i++)
printf("%d\n", arr[i]);
free(arr);
return EXIT_SUCCESS;
}
Note: You need to keep track of arr maximum length.
Note: malloc() leaves garbage value in your pointer, whereas calloc() uses memset() to initialize them to 0.
Note: You need to free the heap allocated resource.
3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int arr[10];
size_t len_arr = sizeof(arr) / sizeof(*arr);
for(size_t i = 0; i < len_arr; i++)
arr[i] = 0;
for(size_t i = 0; i < len_arr; i++)
printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
Note: You can use any of your favorite loop.
4
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int arr[10] = {};
size_t len_arr = sizeof(arr) / sizeof(*arr);
for(size_t i = 0; i < len_arr; i++)
printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
Use calloc function available in stdlib.h
#include<stdio.h>
#include<stdlib.h>
int main(){
int num_cases;
scanf("%d", &num_cases);
int* arr = (int*)calloc(num_cases,sizeof(int));
return 0;
}
To initialize each element of Array you have two approaches:
If you are going for static memory allocation, you can initialize it like this:
int arr[10] = {};
If you are going for dynamic memory allocation, you can use calloc function.
int *arr = (int) calloc(numberOfElementsInArray,sizeOfEachElement);
In your case, it would be like:
int *arr_counter = (int*) calloc(num_cases,sizeof(int));
NOTE: You need to include malloc.h header file to use calloc function.

The pointer problem in C language, does anyone know why the output of this code is different?

The first codeļ¼š
#include <stdio.h>
int *func() {
int n = 100;
return &n;
}
int main() {
int *p = func(), n;
n = *p;
printf("value=%d\n", n);
return 0;
}
output:
value=100
The second code:
#include <stdio.h>
int *func() {
int n = 100;
return &n;
}
int main() {
int *p = func(), n;
printf("c is an interesting language!\n");
n = *p;
printf("value=%d\n", n);
return 0;
}
output:
c is an interesting language!
value=30
I use the debugging program and found that the printf function changed the value of n. What operation does it do inside? If anyone could give me a detailed answer, I would be grateful!

Solving segmentation fault

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main() {
int i,j;
int *u = malloc(10000 * 10000 * sizeof(int));
for (i=0; i<10000; i++)
{
for(j=0;j<10000;j++)
{
u[i][j]=i+j;
}
}
free(u);
}
I edited my program. when compiling this program, I get an error "subscripted value is neither array nor pointer nor vector".
how can i allocate memory?
You have allocated memory for a single dimensional array and you are trying to use it as a two-dimensional array. There is a slight alteration which you need to do to your code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
int i,j;
int *u = malloc(10 * 10 * sizeof(int));
for (i=0; i<10; i++)
{
for(j=0;j<10;j++)
{
u[10*i +j]=i+j; // this is how you can use it
}
}
for (i=0; i<10; i++)
{
for(j=0;j<10;j++)
{
printf("%d ",u[10 *i +j]);
}
printf("\n");
}
free(u);
return 0;
}
Note that I have used size 10*10, you can do the same for whatever size you need.
Check-here
You can't allocate large arrays on heap directly in the declaration.
You can allocate large arrays using malloc as follows
#include <stdlib.h>
int *matrix = malloc(ROW * COLUMNs * sizeof(int));
Always use column major order to search for elements.
Explanation for column major order can be found here Accessing elements in a matrix
Here size = 10000
Always after you complete your task,free the memory
free(matrix);

Hackerrank circular array rotation segmentation faults

My following code sucessfully runs in sample input but gives segmentation faults in 13 test cases.
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
int main(){
int n;
int k;
int q;
int index[q];
scanf("%d %d %d",&n,&k,&q);
int *a = (malloc(sizeof(int) * n));
for(int a_i = 0; a_i < n; a_i++){
scanf("%d",&a[a_i]);
}
for(int a0 = 0; a0 < q; a0++){
int m;
scanf("%d",&m);
index[a0] = m;
}
for(int i=0; i<k; i++){
int ap = a[n-2];
for(int p=1; p<n-1; p++){
a[p] = a[p-1];
}
a[0] = a[n-1];
a[n-1] = ap;
}
for(int j=0; j<q;j++){
printf("%d\n", a[index[j]]);
}
return 0;
}
I am unable to find where the segmentation fault is. Also check out this:where I asked about declaring a as a pointer using malloc
There might have been chances that using malloc() to declare a would have lead to segmentation faults since it does not check for allocation error, but even when i defined a as an array the problem still remained.
q is not initialized, but is used as the argument to the declaration of an array.
You should use malloc to allocate the index array, after reading the value of q.

Null pointer using const instead of variable declaration

I have a problem I can't figure out. I wrote this code to shuffle the elements of an array:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
const char *array[]={"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
int main(int argc, char **argv)
{
int i, tmp, randomize, size;
size = sizeof(array)/sizeof(*array);
srand(time(NULL));
for(i=size;i>0;i--){
randomize=0+(rand()%size);
tmp=(int)array[i];
array[i]=array[randomize];
array[randomize]=(char*)tmp;
}
for(i=0;i<size;i++)
printf("%s", array[i]);
return 0;
}
When I run the program, this is the iutput:
azlngiwexbv(null)uscphqjyrodmtk
I can't understand why the pointer is sometimes null and I can't understand why, changing the source code in this way:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char **argv)
{
char *array[]={"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
int i, tmp, randomize, size;
size = sizeof(array)/sizeof(*array);
srand(time(NULL));
for(i=size;i>0;i--){
randomize=0+(rand()%size);
tmp=(int)array[i];
array[i]=array[randomize];
array[randomize]=(char*)tmp;
}
for(i=0;i<size;i++)
printf("%s", array[i]);
return 0;
}
Everything works fine.
Thanks.
Start loop from size-1, you are pointing out of array in array[size] (first loop iteration).
for (i=size-1; i>=0; i--)
You should avoid casting whenever possible, and it is rarely necessary to do so.
Unless you plan on using argc and argv[], use the simpler form for main(): int main(void). This will remove some compiler warnings, and you should have these enabled; remove all warnings emitted by your compiler.
You cast a pointer to char to int to store it in tmp, and then you cast tmp back to (char *). Just declare tmp as a pointer to char to start with. The first loop counts down from size to 0; this is out of array bounds to start, but why not just use the conventional loop construction: for (i = 0; i < size; i++)? Also, you should consider using size_t for array indices; it is an unsigned integer type guaranteed to be able to hold any array index, and is also the type returned by the sizeof operator.
Further, in your first version you have declared array as an array of pointers to const chars. You can do this, but you need the temporary storage variable tmp to agree with the const type qualifier.
Here is your code with the above changes. There are no casts, it compiles without warnings, and it works.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
const char *array[] = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
const char *tmp;
size_t i, size;
int randomize;
size = sizeof(array) / sizeof(*array);
srand(time(NULL));
for(i = 0; i < size; i++){
randomize = (rand() % size);
tmp = array[i];
array[i] = array[randomize];
array[randomize] = tmp;
}
for(i = 0; i < size; i++)
printf("%s", array[i]);
putchar('\n');
return 0;
}

Resources