Well, I've written a code which basically does:
Asks for array length
User input the array into *p
longestNeg function checks the longest negative sequence.
What it has to do: Return the longest negative sequence with its values.
Problem: in the longestNeg function (throws exception)
if (*arr < 0) {
counter++;
}
Question: Why does it happen?
Question2: Will while (arr < arr + n) work?
Edit3:
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
void longestNeg(int *arr, int n);
int main()
{
int *arr1, n,num = 0,*p;
printf("Please enter the size of the array: ");
scanf("%d", &n);
arr1 = (int*)malloc(n * sizeof(int));
if (arr1 == NULL)
printf("Not enough memory\n");
else printf("Array was allocated!\n" );
for (p = arr1; p < arr1 + n; p++)
{
scanf("%d", p);
}
longestNeg(p - n, n);
free(arr1);
getch();
}
void longestNeg(int *arr, int n)
{
int counter = 0, temp = 0, *p;
for (p = arr; p < arr + n; p++)
{
if (*p < 0) {
counter++;
}
else if (counter > temp) {
temp = counter;
counter = 0;
}
else
counter = 0;
}
if (counter != 0)
for (p = arr; p < arr + counter; p++)
{
printf("%d ", *p);
}
else
printf("No neg numbers.");
}
.....To count the negative numbers, you are incrementing arr past them while checking if they're negative and elapsing counter if so. You then try to print counter numbers from arr, which now points after the negative sequence.
So, just think about it. Imagine that you are a computer. The human has entered 1, 2, -1, -2, -3, -4, 3, 4. You count up - and increment past - the 4 negative numbers. Your pointer arr now points to the penultimate value, 3. The user then asks you to print counter == 4 values from this 3 onwards. But only 2 values are left that belong to the user's allocated region of memory - namely the last pair, 3 and 4.
By trying to use memory that doesn't belong to them, the user invokes undefined behaviour, and the program is perfectly within its rights to do absolutely anything (undefined behaviour) - including segfaulting as it appears to be on your system.
So, stop doing that. Either use a temporary copy of the passed-in pointer arr in your first or both while loops, or do your counting and printing in the same loop. It's really that simple.
Stepping through the problem as though you were the computer is not to be underestimated as a diagnostic tactic that can help you actually think about what you've programmed, if you haven't already.
Two problems: When the loop is done the pointer p points to one beyond the end of the allocated memory. And the second problem is the cause of your problem: You pass a pointer to the pointer to your function which expectes a pointer, leading to undefined behavior.
You should learn to always create function prototype declarations for all your functions, because then the compiler would have been able to catch it and print an error instead of just giving you a warning (which you should have gotten).
Related
I have a function named num_to_binary, which is used to convert a decimal number stored in the form of array. The prototype for this function num_to_binary is as below:
void num_to_binary(int *number_b, int size_of_number);
Here:
number_b is pointer to array which stores my number. For example, if I would like to convert the number 12345 to binary, then I will be storing 12345 in number_b as follows:
number_b[0] = 1
number_b[1] = 2
number_b[2] = 3
number_b[3] = 4
number_b[4] = 5
Also, size_of_number is the number of digits in the number (or it is the number of elements in the array number_b). So for the number 12345, size_of_number has the value 5.
Below is the full declaration of the function num_to_binary:
void num_to_binary(int *number_b, int size_of_number)
{
int *tmp_pointer = malloc(1 * sizeof(int));
int curr_size = 1;
int i = 0;
while(!is_zero(number_b,size_of_number))
{
if(i != 0)
{
curr_size += 1;
tmp_pointer = realloc(tmp_pointer, curr_size * sizeof(int));
}
if(number_b[size_of_number - 1] % 2 == 1)
{
tmp_pointer[i] = 1;
divide_by_2(number_b,size_of_number);
i = i + 1;
}
else
{
tmp_pointer[i] = 0;
divide_by_2(number_b,size_of_number);
i = i + 1;
}
}
int *fin_ans;
fin_ans = malloc(curr_size * sizeof(int));
for(int j = 0 ; j < curr_size; j++)
{
fin_ans[curr_size-1-j] = tmp_pointer[j];
}
}
In the above function:
tmp_pointer: It is initially allocated some memory using malloc(), and is used to store the reverse of the binary representation of the number stored in number_b
curr_size: It stores the current size of tmp_pointer. It is initially set to 1.
i: It is used to keep track of the while loop. It is also used to reallocation purpose, which I have explained a bit later.
is_zero(number_b, size_of_number): It is a function, which returns 1 if the number stored in number_b is 0, else it returns 1.
divide_by_2(number_b, size_of_number): It divides the number stored in number_b by 2. It does NOT change the size of the array number_b.
fin_ans: It is an integer pointer. Since the binary representation stored in the array tmp_pointer will be the reverse of the actual binary representation of the number, so fin_ans will store the correct binary representation of number by reversing the content of tmp_pointer.
Below is the how this function works :
First of all, tmp_pointer is allocated a memory equal to the
size of 1 int. So, now tmp_pointer can store an integer.
We now go into the while loop. The loop will terminate only
when the number stored in number_b equals 0.
Now, we check if i is equal to 0 or not. If it is not equal to
zero, then this means than the loops has been run atleast once, and
in order to store the next binary digit, we resize the memory
allocated to tmp_pointer so that it can store the next bit.
If the last digit of the number is odd, then that implies that the
corresponding binary digit will be 1, else it will be 0. The
if and else condition do this task. They also increment
i each time one of them is executed, and also divide the number by 2.
Now, we are out of the loop. It's time to reverse the binary number
stored in tmp_pointer to get the final answer.
For this, we create a new pointer called fin_ans, and allocate
it the memory which will be used for storing the correct binary
representation of the number.
The last for loop is used to reverse the binary representation
and store the correct binary representation in fin_ans.
The problem:
The code runs for small numbers such as 123, but for large numbers such as 1234567891, it gives a segmentation fault error. This can be checked by trying to print the digits stored in fin_ans.
I tried using GDB Debugger, and got to know that the reason for Segmentation Fault lies in the while loop. I am sure that the functions divide_by_2 and is_zero are not the reason for Segmentation Fault, since I have tested them thoroughly.
I also used DrMemory, which indicated that I am trying to access (read or write) a memory location which has not been allocated. Unfortunately, I am not able to figure out where the error lies.
I suspect realloc() to be the cause of Segmentation Fault, but I am not sure.
Apologies for such a long question, however, I would highly appreciate any help provided to me for this code.
Thanks in advance for helping me out !
There are multiple problems in the code:
you do not check for memory allocation failure
you forget to free tmp_pointer before leaving the function.
you allocate a new array fin_ans to reserve the array tmp_pointer and perform the reverse operation but you do not return this array to the caller, nor do you have a way to return its size. You should change the prototype to return this information.
if the number of zero, the converted number should probably have 1 digit initialized as 0, but you use malloc which does not initialize the array it allocates so tmp_pointer[0] is uninitialized.
you did not provide the code for is_zero() nor divide_by_two(). It is possible that bugs in these functions cause the segmentation fault, especially if the loop does not reach zero and memory is eventually exhausted during this infinite loop.
Here is a modified version:
int *num_to_binary(int *number_b, int size_of_number, int *binary_size) {
int i, j, curr_size;
int *p, *newp;
curr_size = 1;
p = malloc(1 * sizeof(int));
if (p == NULL)
return NULL;
p[0] = 0;
for (i = 0; !is_zero(number_b, size_of_number); i++) {
if (i != 0) {
curr_size += 1;
newp = realloc(p, curr_size * sizeof(int));
if (newp == NULL) {
free(p);
return NULL;
}
p = newp;
}
p[i] = number_b[size_of_number - 1] % 2;
divide_by_2(number_b, size_of_number);
}
for (i = 0, j = curr_size; i < j; i++)
int digit = p[--j];
p[j] = p[i];
p[i] = digit;
}
*binary_size = curr_size;
return p;
}
There is no need for multiple memory reallocations. Result memory buffer size could be easily evaluated as binary logarithm of the decimal input value. Calculation of the number binary representation could also be simplified:
//Transform binary array to actual number
int arr2int(int* pIntArray, unsigned int nSizeIn) {
if (!pIntArray || !nSizeIn)
return 0;
int nResult = 0;
for (unsigned int i = 0; i < nSizeIn; ++i)
nResult += pIntArray[i] * (int)pow(10, nSizeIn - i - 1);
return nResult;
}
int* int2bin(int* pIntArray, unsigned int nSizeIn, unsigned int* nSizeOut){
//0) Converting int array to the actual value
int nVal = arr2int(pIntArray, nSizeIn);
//1)Evaluating size of result array and allocating memory
if(!nVal)
*nSizeOut = 1;
else
*nSizeOut = (int)floor(log2(nVal)) + 1;
//2)Allocate and init memory
int* pResult = malloc(*nSizeOut);
memset(pResult, 0, *nSizeOut * sizeof(int));
//3) Evaluate binary representation
for (unsigned int i = 0; i < *nSizeOut; ++i){
int nBinDigit = (int)pow(2, i);
if (nBinDigit == (nVal & nBinDigit))
pResult[*nSizeOut - i - 1] = 1;
}
return pResult;
}
Testing:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define _DC 9
int main()
{
int test[_DC];
for (int i = 0; i < _DC; ++i)
test[i] = i;
unsigned int nRes = 0;
int* pRes = int2bin(test, _DC, &nRes);
for (unsigned int i = 0; i < nRes; ++i)
printf("%d", pRes[i]);
free(pRes);
return 0;
}
I wrote a function that takes a pointer to an index and checks if it's located within the limits of an array, the function prints the rest of the elements in that array if it's true, and if it's not, it prints "Not in range". The only parameters that this function gets are the array,the length of it and the pointer. The problem I have is that the loop that is responsible for iterating the array and printing the rest of the array also prints garbage values after the last element in the array.
Notes: you can't use any other local variables, only the parameters (array,length,pointer). You also can't use [] operator, only pointer arithmetic.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printAfterX(int* arr, int n, int* x);
int main()
{
int arr[] = { 4, 8, 6, 2, 1, 3, 5, 7, 8, 9, 5 };
printAfterX(arr, 11, arr+6);
return 0;
}
void printAfterX(int* arr, int n, int* x)
{
if (x >= arr && x <= (arr + n)) //this checks if x is in the limits
{
x++;
for (*arr = 0; *arr <= n; *arr++)
{
printf("%d ", *(arr + *x));
}
}
else
{
printf("Not in range ");
}
}
Should be x < (arr + n), not x <= (arr + n). Note that there are a lot of other unchecked conditions in your code. For example, you never check whether or not the element in the array is less than n or not.
If you're not sure whether to use < or <=, you can always do a simple test case in your head: Asssume that your array has two elements, then arr + 0 is valid, arr + 1 is valid, arr + 2 is not. So your n has to be less than 2.
In your for-loop you will always print n numbers, starting from x. Also you set the first element of your array to zero and use it as iterator in for (*arr = 0; *arr <= n; *arr++). As a result you will print numbers that are outside of the range of your array. I would recommend to use another approach on the for-loop like this:
for ( ; x != arr+n; x++)
{
printf("%d ", *x);
}
Based on what you describe as the specification I think there are two problems with this bit of code:
for (*arr = 0; *arr <= n; *arr++)
{
printf("%d ", *(arr + *x));
}
Firstly, that loop is all wrong. You're comparing the current element that arr is pointing at and seeing if it's less than the length of the array. What you should be doing is using n to limit the number of times you go around the loop. You're also making the first element of the array be 0.
Secondly, you're printing random values which could possibly be outside of the array because unless *x is 0, you're not printing some arbitrary value, possibly beyond the end of arr.
Thirdly, your specification says that you want to print everything after the element pointed to by x and you're sort of trying to print everything.
Fixing all three problems you'd end up with code that looks like.
for (x++; x<arr+n; x++)
{
printf("%d ", *arr);
}
and as mentioned elsewhere this if (x >= arr && x <= (arr + n)) should be if (x >= arr && x < (arr + n)) as otherwise you'll be OK if x is one element beyond the length of arr
I have to do as a school assigment small program in C that will read standart input and prints some standart output. To be more specific, it's about reading numbers and sorting them.
(you can skip this, it's just for understanding the code)
First line of the input should determine how many lines of numbers there will be. Second line is ammount of numbers in next line. Third line are to concrete numbers. Fourth line is ammount of numbers in next line and so on until it reaches K number of lines. Restrictions are 0 < K <= 10 (max 10 sequences), each sequence can contain max 10.000.000 numbers and each number's value is max 10.000.000
Example
Input:
2 //which means that there will be 2 sequences (lines) of numbers and their corresponding ammount
3 //in the first sequence there will be 3 numbers
5 99912 45 //first sequence
6 //in the second sequence there will be 6 numbers
9489498 22131 0 521313 7988956 5 //second sequence
Ouptup:
0 5 5 45 22131 99912 521313 7988956 9489498
So I have done a working program but it seems to be unstable with higher values. However I can't determine when and where exactly the program fails. On my computer, I have tested all possible max values and it returned correct output in reasonable time, but on a school server where tests are done it just can't handle high values and fails.
There is one thing, that the program should only use C, not C++, but I am not very sure of differences between them and as I was using C++ compiler, it's possible that my code isn't just raw C.
I am a C beginner and this is something like "Hello world" for me, so please, can you just quick look through the code and say what can cause the unstability? Thanks
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int k, n, i, y, x, index = 0;
int *numbers = (int*) malloc(100000000 * sizeof(int));
if(numbers == NULL){
exit(1);
}
scanf("%d", &k);
for (x = 0; x < k; x++) {
y = 0;
scanf("%d", &n);
while(scanf("%d", &i) > 0){
numbers[index++] = i;
if(++y == n){
break;
}
}
}
for(y = 0;y < index;y++){ //find and print all 0's, because later I will use 0 as a
//already used (printed) element in array and ignore it
if(numbers[y] == 0){
if(y == index-1){
printf("0");
}else{
printf("0 ");
}
}
}
int smallest, smallestIndex;
for(x = 0;x < index;x++){ //print all other numbers in ascending order
smallest = 0;
for(y = 0;y < index;y++){ //find current smallest number
if((numbers[y] < smallest || smallest == 0) && numbers[y] != 0){
smallest = numbers[y];
smallestIndex = y;
}
}
numbers[smallestIndex] = 0;
if(smallest > 0){
if(x == index-1){
printf("%d", smallest);
}else{
printf("%d ", smallest);
}
}
}
free(numbers);
numbers = NULL;
return 0;
}
Based on the information you give, I think this is simply a resource limitation on the server. The server simply runs out of memory and your malloc() fails. I suggest you debug or do this:
if(numbers == NULL){
printf("malloc() failed\n");
exit(1);
}
The code for printing the initial zeros is suspicious:
for(y = 0;y < index;y++){ //find and print all 0's, because later I will use 0 as a
//already used (printed) element in array and ignore it
if(numbers[y] == 0){
if(y == index-1){
printf("0");
}else{
printf("0 ");
}
}
Suppose you have a sequence with 0 as the last element (e.g. 1 2 3 4 5 0); i guess this code will print just 0 with no space after it, and the subsequent code will print 1 2 3 4 5, so you will get something like 01 2 3 4 5.
I understand that you want the output to be as beautiful as possible, that is, without a space at the end. Please also note that a newline (\n) at the end of output might be good.
I rewrote beginning parts of your program to get you on the right path. This should help you but I can't be sure since I don't really know what is causing your program to crash.
This implements the realloc function which should make your program drastically more efficient than it is now. If you don't know what realloc is you can read about it here, and here.
#include <stdio.h>
#include <stdlib.h>
#define BUFFER 256 //for memory management
int main(void)
{
int k, n, i, y , x, index = 0, bff; //declare integer 'bff' and set it to BUFFER
int *numbers = NULL, *tmp; //declare a pointer (numbers) for allocated memory, and a pointer (tmp) for the realloc function
if(!(numbers = malloc(BUFFER * sizeof(int)))) //allocate space for 'bff' integers
{
exit(1); //allocation failed
}
scanf("%d", &k);
for (x = 0; x < k; x++)
{
scanf("%d", &n);
while(scanf("%d", &i) > 0)
{
if(bff <= index) //if the size of index grows larger than the amount of space we allocated
{
bff += BUFFER; //increase the size of bff by BUFFER
if(!(tmp = realloc(numbers, bff * sizeof(int)))) //resize our allocated memory block using the tmp pointer
{
free(numbers); //allocation failed so free already allocated memory
exit(1); //and terminate the program
}
numbers = tmp; //make numbers point to the same location as tmp
numbers[index++] = i;
if(++y == n) break;
}
}
}
.
.
.
free(numbers);
return 0;
}
Keep in mind there are more efficient ways to use realloc. I just posted this here to get you on the right track. Good luck!
You are allocating the wrong amount of memory. The specification states that each sequence can contain 10 million values whereas you allocate a fixed amount. There may be up to k*10 million values of input, and you cannot know that the amount you allocate is enough.
As pointed out by m0skit0, the problem may also be due to over-allocation.
To fix the problem you should allocate the needed amount of memory, no more, no less.
Use the sequence length provided for each sequence to do that.
Also, you need to check the return value of malloc and realloc. If the return value is NULL then the allocation failed and you should print an error message and exit.
I am participating in Harvard's opencourse ware and attempting the homework questions. I wrote (or tried to) write a program in C to sort an array using bubble sort implementation. After I finished it, I tested it with an array of size 5, then 6 then 3 etc. All worked. then, I tried to test it with an array of size 11, and then that's when it started bugging out. The program was written to stop getting numbers for the array after it hits the array size entered by the user. But, when I tested it with array size 11 it would continuously try to get more values from the user, past the size declared. It did that to me consistently for a couple days, then the third day I tried to initialize the array size variable to 0, then all of a sudden it would continue to have the same issues with an array size of 4 or more. I un-did the initialization and it continues to do the same thing for an array size of over 4. I cant figure out why the program would work for some array sizes and not others. I used main to get the array size and values from the keyboard, then I passed it to a function I wrote called sort. Note that this is not homework or anything I need to get credit, It is solely for learning. Any comments will be very much appreciated. Thanks.
/****************************************************************************
* helpers.c
*
* Computer Science 50
* Problem Set 3
*
* Helper functions for Problem Set 3.
***************************************************************************/
#include <cs50.h>
#include <stdio.h>
#include "helpers.h"
void
sort(int values[], int n);
int main(){
printf("Please enter the size of the array \n");
int num = GetInt();
int mystack[num];
for (int z=0; z < num; z++){
mystack[z] = GetInt();
}
sort(mystack, num);
}
/*
* Sorts array of n values.
*/
void
sort(int values[], int n)
{
// this is a bubble sort implementation
bool swapped = false; // initialize variable to check if swap was made
for (int i=0; i < (n-1);){ // loops through all array values
if (values[i + 1] > values [i]){ // checks the neighbor to see if it's bigger
i++; // if bigger do nothing except to move to the next value in the array
}
else{ // if neighbor is not bigger then out of order and needs sorting
int temp = values[i]; // store current array value in temp variable for swapping purposes
values[i] = values[i+1]; //swap with neighbor
values[i+1] = temp; // swap neighbor to current array value
swapped = true; // keep track that swap was made
i++;
}
// if we are at the end of array and swap was made then go back to beginning
// and start process again.
if((i == (n-1) && (swapped == true))){
i = 0;
swapped = false;
}
// if we are at the end and swap was not made then array must be in order so print it
if((i == (n-1) && (swapped == false))){
for (int y =0; y < n; y++){
printf("%d", values[y]);
}
// exit program
break;
}
} // end for
// return;
}
You can easily use 2 nested for loops :
int i, j, temp ;
for ( i = 0 ; i < n - 1 ; i++ )
{
for ( j = 0 ; j <= n - 2 - i ; j++ )
{
if ( arr[j] > arr[j + 1] )
{
temp = arr[j] ;
arr[j] = arr[j + 1] ;
arr[j + 1] = temp ;
}
}
}
also you should now it's a c++ code not a c, because c doesn't have something like :
int mystack[num];
and you should enter a number when you're creating an array and you can't use a variable (like "int num" in your code). This is in C, but in C++ you're doing right.
The first thing to do when debugging a problem like this is ensure that the computer is seeing the data you think it should be seeing. You do that by printing out the data as it is entered. You're having trouble with the inputs; print out what the computer is seeing:
static void dump_array(FILE *fp, const char *tag, const int *array, int size)
{
fprintf(fp, "Array %s (%d items)\n", tag, size);
for (int i = 0; i < size; i++)
fprintf(fp, " %d: %d\n", i, array[i]);
}
int main(void)
{
printf("Please enter the size of the array \n");
int num = GetInt();
printf("num = %d\n", num);
int mystack[num];
for (int z = 0; z < num; z++)
{
mystack[z] = GetInt();
printf("%d: %d\n", z, mystack[z]);
}
dump_array(stdout, "Before", mystack, num);
sort(mystack, num);
dump_array(stdout, "After", mystack, num);
}
This will give you direct indications of what is being entered as it is entered, which will probably help you recognize what is going wrong. Printing out inputs is a very basic debugging technique.
Also, stylistically, having a function that should be called sort_array_and_print() suggests that you do not have the correct division of labour; the sort code should sort, and a separate function (like the dump_array() function I showed) should be used for printing an array.
As it turns out the reason why it was doing this is because when comparing an array's neighbor to itself as in:
if (values[i + 1] > values [i])
The fact that I was just checking that it is greater than, without checking if it is '=' then it was causing it to behave undesirably. So if the array is for example [1, 1, 5, 2, 6, 8] then by 1 being next to a 1, my program did not account for this behavior and acted the way it did.
I'm new to C and I'm having a small problem with my code:
int i, n;
int *arr;
while(n != 0) {
scanf("%d", &n);
if(n == 0)
exit(1);
else {
arr = (int*) malloc(sizeof(int) * n);
for(i = 0; i < n; i++)
scanf("%d", &arr[i]);
} //end if
} //end while
What I'm trying to do is to make an array of n size and I want to stop reading when I get a '0' for example if I enter:
3
2
2
5
2
6
7
0
I want an array of size 3 with values 2, 2, 5, an array of 2 with values 6 and 7 and exit because of the 0
* Sorry, I left out an important part I think... In my code a call a calc() where I send arr, right after scanf("%d",&arr[i]) and then i'll return the value and then if the next values e.g. 2 isn't 0 I'll read, create a new array, send arr, print result on console and again if the next value is 0 then it will exit. *
Could you guys tell me where I'm wrong?
You are almost there!
You are creating the new arrays in arr, but this is a single pointer so can only refer to one block of memory. When you call malloc the new memory is stored in arr but the old memory is lost. You are 'leaking memory' because the machine has the old memory reserved but you don't have a variable storing it's address so you have no way to find it again.
If you only need to store the last list you should free the old memory (in arr) before malloc'ing the new space. If you need to store all the arrays you will need an array of pointers in arr.
edit:
You need to call free to 'free' the previously allocated memory before you allocate the new memory. At the first set of data you don't have any existing 'malloc' but it's always safe to free a NULL pointer, so simply set the pointer to NULL at the start.
Hint: It's always a good idea to set all the variables to some safe initial value when you define them.
int *arr=NULL; // Mark this as pointing to no memory
....
free(arr); // first time it does nothing, afterwards it deletes the previous reserved memory
arr = (int*) malloc(sizeof(int) * n); // as before this reserves some memory
The problems which are visible in your code are:
1. Checking uninitialized integer n in while. To fix this either initialize n to non zero or use a do{ ... } while() instead of while().
2. You need to validate the value of n which is read through scanf. malloc takes size_t type as the parameter which is unsigned int. But n being an integer can accept negative values, thus if a negative value is entered it will be passed as unsigned int to malloc, this may lead to undesired results (Also for loop will be executed incorrect number of times). You may also consider changing the type of n from integer to unsigned int type or change the exit condition to if( n < 1 ).
3. There is memory leak in your program. Memory allocated through malloc is not freed through free.
4. Do not assume that malloc will always succeed. Please check for the success of malloc through a NULL check i.e.
if (NULL == arr)
{
//error handling
}
5. exit with non zero value generally indicates abnormal termination. You can use break or return. break might be a better idea as it generally gets difficult to test a function as the exit points in the function increase (though this may not be true in your case, but it is FYI)
6. Optionally, you can check the return value of scanf to make sure that a valid input was entered.
Help this helps!
You're not initializing n so you may or may not enter your while loop. Starting n at -1 would be a reasonable thing to do:
int i, n = -1;
And you should cast the return value of malloc, that can hide problems.
You're also leaking memory because you're not calling free on that you get back from malloc and you're losing track of what you read in every time you assign a new value to arr. Brian Roach and Martin Becket have mentioned these things though.
Presumably you want to be able to access these arrays later.
As it is, you're losing your pointer to the previous array when you malloc the next one (and of course, causing a memory leak if it were a larger application).
You need to allocate a chuck of int * (a set of int pointers) then store each int pointer there.
The trick is ... if you don't know how many arrays you're going to need, you need your code to be dynamic (for example; allocate some amount of space, then allocate more if you run out).
Another option is that you could limit the number of series the user can input and tell them they're done when they reach it.
Here's some help if you wanted to go the latter route:
int i;
int n = 1;
int **myArrayOfArrays = malloc(sizeof(int*) * 5); /* max of 5 arrays */
int *arr;
int arrayCount = 0;
while(n != 0) {
scanf("%d", &n);
if(n == 0)
break;
else {
if (arrayCount == 4) {
printf("Woah there partner! That's enough!\n");
break;
}
else
{
arr = malloc(sizeof(int) * n);
for(i = 0; i < n; i++)
scanf("%d", &arr[i]);
myArrayOfArrays[arrayCount] = arr;
arrayCount++;
}
} //end if
} //end while
HOWEVER ... now you don't know how long each array is. Which is a problem. You'd need to keep track of that, or use a dynamic structure such as a linked list. In the example below, we add the length as the first element of each array:
int main()
{
int i;
int n = 1;
int **myArrayOfArrays = malloc(sizeof(int*) * 5);
int *arr;
int arrayCount = 0;
while(n != 0) {
scanf("%d", &n);
if(n == 0)
break;
else {
if (arrayCount == 4) {
printf("Woah there partner! That's enough!\n");
break;
}
else
{
arr = malloc(sizeof(int) * (n + 1)); /* one more than we need */
arr[0] = n; /* store the array length in the first element */
for(i = 1; i <= n; i++)
scanf("%d", &arr[i]);
myArrayOfArrays[arrayCount] = arr;
arrayCount++;
}
} //end if
} //end while
int j;
for (i = 0; i < arrayCount; i++)
{
int length = myArrayOfArrays[i][0]; /* retrieve the length */
for (j = 1; j <= length; j++)
printf("%d ", myArrayOfArrays[i][j]);
printf("\n");
}
}
Dynamic allocation using arrays / raw memory means you need to keep track of stuff. The better approach really is using a linked list for your data. In this case, you could have a linked list of nodes, each of which contained a link list of integers.