I am trying to save strings into the array and then print them but after the first record is saved the whole array is (according to Visual Studio debugger) filled with nonsense. What am I doing wrong?
int saveRecord(int ixA, int ixB, int length, int* ocupied, char**arr)
{
char r[50];
sprintf(r,"%d: %d - %d", length, ixA, ixB);
arr[*ocupied] = r;
(*ocupied)++;
return 0;
}
int printRecords(int ocupied, char** arr)
{
for (int i = 0; i < ocupied; i++)
{
printf("%s\n", arr[i]);
}
printf("Options: %d\n", ocupied);
return 0;
}
int main()
{
int length = 0, ixA = 0, ixB = 0;
int* ocupied;
int a = 0;
ocupied = &a;
char r[50] = "";
char *arr[250000];
for (int i = 0; i < 250000; i++)
{
arr[i] = "";
}
for (int i = 0; i < 10; i++)
{
scanf("%d %d %d", &ixA, &ixB, &length);
saveRecord(ixA, ixB, length, ocupied, arr);
}
printRecords(*ocupied, arr);
}
The problem is in saveRecord:
char r[50];
sprintf(r,"%d: %d - %d", length, ixA, ixB);
arr[*ocupied] = r;
You're setting a value in your array to r, which is a local array. In this context, arr[*ocupied] contains a pointer to the first element of r. When saveRecord reuturns, r goes out of scope, so the pointer you saved off now points to invalid memory. Returning a pointer to a local variable and subsequently dereferencing it invokes undefined behavior.
Since you want this data to persist outside of the function, you need to dynamically allocate memory instead of using a local variable:
// find out exactly how much space is needed
int len = snprintf(NULL, 0, "%d: %d - %d", length, ixA, ixB);
arr[*ocupied] = malloc(len + 1);
snprintf(arr[*ocupied], len + 1, "%d: %d - %d", length, ixA, ixB);
Related
whan I enter a bigger size to the array every thing just goes fine.
but if I put a smaller size it's just change the value in the array to some garbage value. Someone know's why?
int resize(int* calc, int size)
{
int new_number = 0, i = 0;
printf("Enter new number of grade: ");
scanf("%d", &new_number);
calc = (int*)realloc(calc, new_number * sizeof(int));
if (new_number > size)
{
for (i = size + 1; i <= new_number; i ++)
{
printf("Enter grade %d: ", i);
do
{
scanf("%d", &calc[i - 1]);
} while (check_valid(calc, i));
}
size = new_number;
}
return size;
}
The value returned from realloc() may be different from what is passed.
The argument calc is a copy of what is passed, so modification of that will not affect what is passed.
To update the array correctly, you should receive a pointer to the pointer so that the pointer can be updated from the resize() function.
Also:
It looks weird to return old size when new size is smaller than new size while resizing is done in both case.
Casting results of malloc() family is considered as a bad practice.
Try this (make calc pointer to int* and add dereferences):
int resize(int** calc, int size)
{
int new_number = 0, i = 0;
printf("Enter new number of grade: ");
scanf("%d", &new_number);
*calc = realloc(*calc, new_number * sizeof(int));
if (new_number > size)
{
for (i = size + 1; i <= new_number; i ++)
{
printf("Enter grade %d: ", i);
do
{
scanf("%d", &(*calc)[i - 1]);
} while (check_valid(*calc, i));
}
}
return new_number;
}
and the calling will be like this:
int size = 0;
int* calc = NULL;
size = resize(&calc, size); /* add & to pass the pointer to the pointer */
instead of one for original function int resize(int* calc, int size):
int size = 0;
int* calc = NULL;
size = resize(calc, size);
I have a problem where I have this structure
typedef struct _COMPLEX {
double real, imag;
}COMPLEX;
and I need to declare an array of this structure and sum the elements of the array. Here is my code.
#include <stdio.h>
#include <stdlib.h>
void* xmalloc(size_t nrOcteti);
int main()
{
COMPLEX* v = 0, *s = 0;
int n, i;
printf("\n n = ");
scanf("%d", &n);
v = (COMPLEX*)xmalloc((n)*sizeof(COMPLEX));
s = (COMPLEX*)xmalloc(sizeof(COMPLEX));
for(i = 0; i < n; i++)
{
printf("\n v[%d].real and imag:", i);
scanf("%lf %lf", &v[i].real, &v[i].imag);
}
for(i = 0; i < n; i++)
printf("V%d after scan=%.2lf + %.2lf * i\n", i, v[i].real, v[i].imag);
s->real = 0; s->imag = 0;
for(i = 0; i < n; i++)
{
s->real = s->real + v[i].real;
s->imag = s->imag + v[i].imag;
}
for(i = 0; i < n; i++)
printf("V%d after sum=%.2lf + %.2lf * i\n", i, v[i].real, v[i].imag);
printf("\nS=%lf + %lf\n", s->real, s->imag);
if(s) free(s);
s = 0;
if(v) free(v);
v = 0;
return 0;
}
void* xmalloc(size_t nrOcteti)
{
void *p = 0;
p = malloc(sizeof(nrOcteti));
if(!p)
{
fprintf(stderr, "Allocation failed!");
exit(EXIT_FAILURE);
}
return p;
}
After I give the elements of the array I print them everything is alright, but just before the sum the elements of the array are changed(and for multiple test, apparently the element with the index 2 is modified) and the sum at the end is incorrect. And sometimes(I think because of different inputs) it gives me at the end Segmentation fault because of the free().
The array and sum needs to be pointers to that struct and need to be dynamically allocated.
I tried many times and I can't manage to make it work properly.
If somebody can help me solve this it will be a blessing =))
The line
p = malloc(sizeof(nrOcteti));
in the function xmalloc() is wrong. This line is ignoring what is passed as the argument and just allocating for one size_t.
It should be
p = malloc(nrOcteti);
to allocate specified size.
This question already has an answer here:
Dynamic memory access only works inside function
(1 answer)
Closed 5 years ago.
I have to write function to read the array length and the array and make that array able to be used in other functions.
I have read many things about pointers but I didn`t find an answer to my question.
Here is my code.
int readArray(int *ar, int *pointer){
int i, length;
scanf("%d", &length);
ar = (int *) malloc(length * sizeof(int));
for(i = 0; i < length; i++){
scanf("%d", pointer + i);
}
return length;
}
void printArray(int *pointer, int length){
int i;
for(i = 0; i < length; i++){
printf("%d ", *(pointer + i));
}
}
int main(){
int *pointer, *ar, length;
pointer = ar[0];//Here I get the warnings.
length = readArray(ar, pointer);
printArray(pointer, length);
return 0;
}
The warnings in codeblocks:
warning: assignment makes pointer from integer without a cast
and
warning: 'ar' is used uninitialized in this function [-Wuninitialized]|.
This question is different from this Dynamic memory access only works inside function because i have to read the array length in the readArray function. And for me, as a begginer, only little difference is a big difference.
I would consider with 2 options. One returns pointer to array and saves length as pointer and another returns length but accepts pointer to pointer as parameter.
Option 1: Return pointer of array and pass pointer to length parameter
This option will return pointer to allocated and filled array and length will be saved to pointer passed as parameter
int* readArray(int* length) {
int* arr;
//Scan for length
scanf("%d", length);
//Allocate memory
arr = (int *)malloc(...);
//Fill data
...
return arr;
}
and I will use it like this:
int length;
int *pointer;
pointer = readArray(&length);
printArray(pointer, length);
Option 2: Pass pointer to pointer to array and return length of array
int readArray(int ** ar) {
int length;
....
*ar = (int *)malloc(...);
...
return length;
}
Usage:
int* ar;
int length;
length = readArray(&ar);
printArray(ar, length);
I would go with this option.
You actually want this:
int readArray(int **ar) {
int i, length;
scanf("%d", &length);
*ar = (int *)malloc(length * sizeof(int));
for (i = 0; i < length; i++) {
scanf("%d", &(*ar)[i]);
}
return length;
}
void printArray(int *pointer, int length) {
int i;
for (i = 0; i < length; i++) {
printf("%d ", *(pointer + i));
}
}
int main() {
int *ar, length;
length = readArray(&ar);
printArray(ar, length);
return 0;
}
Variables are passed by value in C, included pointers. With your solution:
int readArray(int *ar, int *pointer){
int i, length;
scanf("%d", &length);
ar = (int *) malloc(length * sizeof(int));
for(i = 0; i < length; i++){
scanf("%d", pointer + i);
}
return length;
}
ar is a local variable to readArray and pointer will never get modified in main.
Consider this:
void foo(int bar)
{
bar = 123;
}
...
int a = 1;
foo(a);
// a won't contain 123 here
So I'm trying to write a function that'll search a word in a 2D bulk.
The function returns an (int) array of size [3] with values as the answer.
Here is my main() function:
void main() {
char bulk[L][L];
for (int i = 0; i < L; i++) {
for (int j = 0;j < L;j++)
scanf_s(" %c", &bulk[i][j]);
}
int *arr = search(&bulk, L, "bc");
printf("ARR: %d, %d, %d\n", arr[0], arr[1], arr[2]);
}
And here's the search() function:
int *search(char(*bulk)[L], int size, char *word) {
int arr[3] = { 0,0,0 };
int flag = 9;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (bulk[i][j] == *word) {
if (checkRight(bulk, i, j, word)) flag=0;
}
if (flag != 9) {
arr[0] = i;
arr[1] = j;
arr[2] = flag;
printf("ARR: %d, %d, %d\n", arr[0], arr[1], arr[2]);
return arr;
}
}
}
return arr;
}
The checkRight() function works well, it returns 0/1 for if the word exists to the right. The problem is that the two printf's are printing different values.
Output for search(): "ARR: 0,1,0".
Output for main(): "ARR: -858993460, -858993460, 0".
I assume it's pointer-related but I'm struggling with finding the problem. Any ideas?
Thanks a bunch!
return arr;
In here you are returning the address of the first value in the array, this address points to a temporary value inside the stack frame of the function search.
try to pass arr as a parameter or using "static int arr[3]" in order to make the array not temporary.
So for some Uni work I need to create an array using a function (my first time with C functions and pointers) but store the array as a pointer because i dont think C can use arrays in functions? And then also use another function to print out each element in the array. The code i use in main is:
int* x = get_lotto_draw();
print_array(x);
And then my functions are:
int* get_lotto_draw() //Returns an array of six random lottery numbers 1-49
{
int min = 1;
int max = 49;
int counter = 0;
srand(time(NULL));
int r = rand()%(max-min)+min;
int *arrayPointer = malloc(6 * sizeof(int));
for(counter = 0; counter <= 5; counter++)
{
arrayPointer[counter] = r;
}
return arrayPointer;
}
void print_array(int * array) //Print out the content of an array
{
int i = 0;
int printerArray[6] = {0, 0, 0, 0, 0, 0};
for(i = 0; i <= 5; i++)
{
printerArray[i] = array[i];
}
printf("array = %d", array);
printf("printerArray = %d", printerArray);
for(i = 0; i <= 5; i++)
{
printf("Array element %d : %d\n", i, printerArray[i]);
}
}
But im doing something wrong, and either the array isnt getting created correctly, or the print isnt working correctly. Thanks for your time.
What you want is:
void print_array(int * array) //Print out the content of an array
{
int i = 0;
for(i = 0; i <= 5; i++)
{
printf("Array element %d : %d\n", i, array[i]);
}
}
Following two lines could provoke undefined behavior
printf("array = %d", array);
printf("printerArray = %d", printerArray);
you can't use %d here, as array and printerArray decays to pointers in this context and in order to print pointer you should use %p and cast your arrays to void * (thanks to #user3447428 for his comment about cast )