Allocating memory for array in struct (in C) - c

I need to define a type-struct in C that contains an array to be malloc'd as:
#include <stdio.h>
#include <stdlib.h>
typedef struct mine
{
int N;
double *A;
} mine;
int main(int argc, char** argv)
{
int i;
mine *m=malloc(sizeof(mine));
printf("sizeof(mine)=%d\n",sizeof(mine));
scanf("Enter array size: %d",&(m->N));
m->A=malloc((m->N)*sizeof(double));
for(i=0; i < m->N; i++)
m->A[i]=i+0.23;
printf("First array element: %lf",m->A[0]);
return (EXIT_SUCCESS);
}
The program compiles and runs, and the integer assignment seems to work fine. The array is not working as it should, however.
Any suggestions? I would like m to remain a pointer (to pass to functions etc.).
Thanks.

This is your problem:
scanf("Enter array size: %d",&(m->N));
It should be two separate steps:
printf("Enter array size: ");
scanf("%d",&(m->N));
(and for debugging checking:)
printf("The size entered appears to be %d\n", m->N);
That way, you know if you got the value you intended to get!

If #abelenky answered your question fine, but I was always told to cast the results of malloc from the void * it returns into whatever you are actually working with.
mine *m = (mine *)malloc(sizeof(mine));

Related

Adding pointers to an array of pointers

I'm trying to make a program that for a given int value keeps the amount of dividers:
int amount_of_dividers and a list of those dividers: int* dividers
This is the code:
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int value;
int amount;
int* dividers;
} Divide;
int main(){
Divide ** tt;
read_dividers(tt,5);
}
/* the functions "amount_of_dividers(int g)" and "dividers_of(int g, int amount)"
used in void read_divider are working properly, they are not needed for this question */
void read_divider(Divide *g){
scanf("%d",&(g->value));
g->amount = amount_of_dividers(g->value);
g->dividers = dividers_of(g->value,g->amount);
}
/* assuming that read_divider works, what causes read_dividerS to crash? */
void read_dividers(Divide ** t, int amount){
int i = 0;
t = malloc(amount*sizeof(Divide*));
for(i = 0;i<amount;i++){
read_divider(t[i]);
}
}
Read_dividers uses an array of pointers **t where i'm trying to fill each element of this array with a pointer to a Divide g variable.
EDIT: input in this case in main() : "read_dividers(tt,5)" means the user gives 5 int's, which get converted to 5 Divide structs.
What happens instead is the program crashes after I give in the second int
If any more information is missing, don't hesitate to ask!
You are passing an uninitialized t[i] to read_divider. t is supposed to be pointer to pointer to Divide, not pointer to Divide, you may have just got lucky on your first pass, but I suspect it failed on the very first call.

Change Array without returning it [C]

I just have a basic question concerning arrays in functions.
I am trying to change an array in a function without returning it.
I know how to do this for integers or doubles but i didn't know how to do this for arrays. So i experimented a little bit and now I am confused.
I have 2 variations of my code which i thought should do the same thing , but they don't. I pass the array b to the function Test. In the function I try to fill the array with the values 0, 1 ,2
#include <stdlib.h>
#include <stdio.h>
void Test(int * vector){
vector = malloc(3*sizeof(int));
int i;
for(i=0;i<3;i++){
*(vector+i)=i;
}
}
int main(){
int b[3];
Test(b);
printf("%i\n",b[0]);
printf("%i\n",b[1]);
printf("%i\n",b[2]);
return EXIT_SUCCESS;
}
This Version doesnt work, i don't get the expected result 0,1,2
This Code on the other hand does seem to work:
#include <stdlib.h>
#include <stdio.h>
void Test(int * vector){
int * b = malloc(3*sizeof(int));
int i;
for(i=0;i<3;i++){
*(b+i)=i;
*(vector+i) = *(b+i);
}
}
int main(){
int b[3];
Test(b);
printf("%i, ",b[0]);
printf("%i, ",b[1]);
printf("%i ",b[2]);
return EXIT_SUCCESS;
}
Can somebody explain to me why only the second one works?
Best Regards,
Rob
When you pass an array to a function, it decays into a pointer to the first element. That's what the function sees. But then you take the function parameter vector and overwrite it with dynamically allocated memory. Then you don't have access to the array you passed in. Additionally, you have a memory leak because you didn't free the allocated memory.
In the case of the second function you don't modify vector, so when you dereference the pointer you're changing b in main.
Also, instead of this:
*(vector+i)
Use this:
vector[i]
It's much clearer to the reader what it means.
test doesn't need to call malloc(). When you use an array as a function argument, it passes a pointer to the array. So you can simply write into vector[i] and it will modify the caller's array.
void Test(int * vector){
int i;
for(i=0;i<3;i++){
*(vector+i)=i;
}
}

Pass arrays to function

Apologies for this re-post as I do not know how to phrase my question as it is my first time using stack overflow. I hope someone could help me out in this quiz for my studies.
I had research on this program but I do not know if it relates to the quiz question on arraySize.
Question is below:
we pass array ai to function fillArray. What exactly is passed to the function? The answer is a single memory address, not the 10 integers! This is why we can use the function to fill the array ai with 10 numbers.
Complete the above function fillArray so that it reads arraySize number of integers from the user and fill the array with those numbers.
Write a driver program to test the function with integer arrays of different sizes.
Note the formal parameter int array[] in function fillArray can be changed to int *array. Verify this by modifying and testing your code.
My code is below:
#include <stdio.h>
#define MAX 10
int fillArray(int array[], int arraySize);
void print_intaray(int array[], int arraySize);
main()
{
int ai, exam_scores[MAX];
printf("***List of Array***\n\n");
ai = fillArray(exam_scores, MAX);
print_intaray(exam_scores, ai);
}
int fillArray(int array[], int arraySize)
{
int ai, count = 0;
printf("Type array, EOF to quit\n");
while ((count < arraySize) && (scanf("%d", &ai) !=EOF))
{
array[count] = ai;
count++;
}
return count;
}
void print_intaray(int array [], int arraySize)
{
int i;
printf("\n***Your Arrary***\n\n");
for (i = 0; i<arraySize; i++)
printf("%d\n", array[i]);
}
I'm new to programming and I hope my question could somehow be resolve.
Thanks for viewing :)
Assuming the question is "Why are int array[] and int *array equivalent in the function argument":
I'm not much of a C expert, but AFAIK arrays (in C) are largely just pointers to which you append a certain offset. Telling C you expect an int myarray[] means pretty much the same as expecting a pointer to an integer (int *array). If you increment the pointer, you can access the next element in the array. This is also known as pointer arithmetic.
The C compiler translates array syntax like foo[3] in the background to something like *(*foo+3), but you can also do that yourself by just dealing with the pointers.

Segmentation fault (core dumped) in the following code. What's wrong?

I am relatively new to C. I have encountered quite a few segmentation faults but I was able to find the error within a few minutes. However this one's got me confused. Here's a new function I was trying to write. This basically is the C equivalent of the python code
r=t[M:N]
Here's my C code with a test case
#include <stdio.h>
char* subarraym(char* a, int M, int N)
{
char* s;
int i;
for (i=M; i<N; i++){ s[i-M]=a[i]; }
return s;
}
main()
{
char* t="Aldehydes and Ketones";
char* r=subarraym(t,2,10);
printf("%c\n",r[4]);
return 0;
}
The expected answer was 'd'. However I got a segmentation fault.
Extra Info: I was using GCC
Your code will not work because your sub-array pointer is never initialized. You could copy the sub-array, but then you will have to manage the memory, and that's overkilling for your problem.
In C, arrays are usually passed around as pairs of pointer and number of elements. For example:
void do_something(char *p, int np);
If you follow this idiom, then getting a sub-array is trivial, assuming no overflow:
void do_something_sub(char *p, int np, int m, int n)
{
do_array(p + m, n);
}
Checking and managing overflow is also easy, but it is left as an exercise to the reader.
Note 1: Generally, you will not write a function such as do_something_sub(), just call do_something() directly with the proper arguments.
Note 2: Some people prefer to use size_t instead of int for array sizes. size_t is an unsigned type, so you will never have negative values.
Note 3: In C, strings are just like char arrays, but the length is determined by ending them with a NUL char, instead of passing around the length. So to get a NUL-terminated substring, you have to either copy the substring to another char array or modify the original string and overwrite the next-to-last char with the NUL.
From
...,10);
you expect to receive 10 char (+1 0-terminator), so provide it to the function somehow.
Not doing so, but writing to invalid memory by
char * s; /* note, that s is NOT initialised, so it points "nowhere". */
...
s[i-M] = ...
provokes undefined behaviour.
Possible solution to provide memory for such a case can be found in this answer: https://stackoverflow.com/a/25230722/694576
You need to secure the necessary memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* subarraym(char *a, int M, int N){
if(N < 0){
N += strlen(a);
if(N < 0)
N = 0;
}
int len = N - M;
char *s =calloc(len+1, sizeof(char));//memory allocate for substring
return memcpy(s, &a[M], len);
}
int main(){
char *t="Aldehydes and Ketones";
char *r=subarraym(t,2,10);
printf("%c\n",r[4]);
free(r);
return 0;
}

Sorting words runs perfectly locally but gives runtime error online

My word sort program gets compiled and runs perfectly on my computer but gives runtime error when submitted online. Locally it takes input and provides correct output. I'm unable to understand what is causing this error.
#include <stdio.h>
#include <string.h>
void sort_word(char word[100][10],int n);
int main(){
int i,n;
char word[100][10];
scanf("%d\n",&n);
for(i=0;i<n;i++){
scanf("%s",word[i]);
}
sort_word(word,n);
for(i=0;i<n;i++){
printf("%s\n",word[i]);
}
return 0;
}
void sort_word(char word[100][10], int n)
{
int i,j;
char *tmp,s;
tmp=&s;
for(i=0;i<n;i++){
for(j=0;j<n-1;j++){
if(strcmp(word[j],word[j+1])>0){
strcpy(tmp,word[j]);
strcpy(word[j],word[j+1]);
strcpy(word[j+1],tmp);
}
}
}
}
char *tmp,s;
tmp=&s;
This is wrong for what you are trying to achieve.
tmp will be pointing to an array of only 1 character (or simply, to a character).
What you want is a temporary buffer of size 10 (which seems to be the max size you have chosen for your words)
You can simply declare it as a single dimension array : char tmp[10]

Resources