1

Please pardon me if you find this question to be very basic. I tried for several hours, just don't seemed to understand why my codes below doesn't work. I just want to insert some int values into an int pointer and print it out.

int val, x;
int *ptr;  
ptr = malloc(sizeof(int));  

do
{
    scanf("%d", &val);
    *ptr = val;
    ptr++;
}while(val < 20);    


for(x=0; x<5; x++)   //Print values *ptr          
{
    printf("ptr[%d]: %d\n", x, *ptr);
    ptr++;
}

The code can compile. But the output is wrong. Input: 4 5 6 7 8 20

Output:

ptr[0]: 20
ptr[1]: 4063428
ptr[2]: 62261273
ptr[3]: 134267354
ptr[4]: 4067081
7
  • 3
    I would gladly accept anyone's answer who can tell me what is the proper way of receiving n number of inputs using a loop into pointer (without risking segmentation fault). Anyone?? Commented Nov 3, 2014 at 0:46
  • Please edit your post to explain that that is really your problem. Commented Nov 3, 2014 at 0:51
  • these two lines: *ptr = val; ptr++; are collectively wrong. There is only room for one int int the memmory allocated and pointed to by ptr. So, one value can be placed at *ptr, but the ptr++ steps past the allocated memory (and loses the pointer to the allocated memory, resulting in a memory leak as the allocated memory pointer cannot be passed to free() Commented Nov 3, 2014 at 0:59
  • all de-referencing of the ptr pointer beyond ptr[0] (or *ptr) is to unallocated memory (undefined behaviour) and can result in a seg fault event. Commented Nov 3, 2014 at 1:09
  • are you sure that this line: ptr++; inside the do...while loop is actually in the executing code, because the output says it is not. Commented Nov 3, 2014 at 1:16

4 Answers 4

5
#include <stdio.h>
#include <stdlib.h>

int main(void){
    int val, x = 0, i;
    int *ptr, *p;  
    ptr = NULL;  

    while(1== scanf("%d", &val) && val < 20){
        if(NULL!=(p = realloc(ptr, (x+1)*sizeof(*p))))//extend a secure memory
            ptr = p;//Update Now that realloc have successfully extended
        else {
            fprintf(stderr, "realloc error!\n");
            free(ptr);
            exit(-1);
        }
        ptr[x++] = val;
    }  

    for(i=0, p=ptr; i<x; i++){
        printf("ptr[%d]: %d\n", i, *p++);
    }
    free(ptr);
    return 0;
}
Sign up to request clarification or add additional context in comments.

16 Comments

@Kyborek I seem a value outside the specified range is not required. and In the case of manual input and would not be so in large size.
@user3629249 BLUEPIXY's way (using sizeof(*p)) is better practice than sizeof(int) because you do not have to change it if you change the type of ptr e.g. you want change your code to read floats.
@Kyborek At least OP can learn to check his allocations this way. Personally I would prefer it if he did else exit(EXIT_FAILURE); but showing or mentioning the check in an answer is better than not.
@user3629249 There is no need to add " " in order to skip the \n.
@user3629249 There is no difference either at the moment of the code.
|
1

First of all you need enough space for lots of ints.

ptr = malloc(100 * sizeof(int));  

There is no "automatic growing" of arrays in C, you have to explicitly write such a thing.

Then you have to make sure not to lose the value of ptr. If you do ptr++ then it will be difficult to get back to the start of the array to print it out later. Also you have to make sure you don't exceed the bounds of what you have allocated.

One way to do that is to use an index:

for (size_t index = 0; index < 100; ++index)
{
    scanf("%d", &val);
    ptr[index] = val;

    if ( val >= 20 )
        break;
}

Similarly use an index for your output loop, and use the actual number of values entered instead of 5:

for(x=0; x< index; x++)   //Print values *ptr          
{
    printf("ptr[%d]: %d\n", x, ptr[x]);
}

4 Comments

Correct me if I am wrong. I thought C pointer can dynamically grow to any size (as long as there is enough memory in the computer). Won't ptr = malloc(100 * sizeof(int)); limit the size, and makes it not dynamic?
it will not grow by itself, you will need to realloc it if you need larger size. Also i would suggest removing val and loading the values with scanf right into ptr[index]
@user3437460 You can indeed allocate memory up to whatever amount of memory the OS will let you have but you must manually call an allocation function to do so. For growing an existing allocation, use realloc
@user3437460 you will need to keep track of how much memory you have allocated, and use the realloc function if you need more.
0

if you allocate the pointer only enough memory for 1 value:

ptr = malloc(sizeof(int));  

you cannot expect to stuff 20 values into it. You are writing out of your allocated memory and you are only lucky that your program didn't get segmentation fault.

If you want to load unknown amount of numbers you need to reallocate the array once it is full. for example: store its size, amount of elements. load elements until it is full, use realloc to increase size to double, repeat as long as you need. The task itself sounds simple but it is kind of complicated. If you don't mind using C++ vector would save you lots of work.

3 Comments

While this is correct, it is not the only problem preventing OP from getting the output he wants.
I am aware of that, i just don't see what exactly OP wants
OP has thankfully just added a comment clarifying this.
-1

there may be three mistake in this code

int val, x;
int *ptr;  
ptr = malloc(sizeof(int));  //mistake 1

do
{
    scanf("%d", &val);
    *ptr = val;
    ptr++;                 //mistake 2
}while(val < 20);    


for(x=0; x<5; x++)   //Print values *ptr, mistake 3
{
    printf("ptr[%d]: %d\n", x, *ptr);
    ptr++;
}

- let's look into No.1:

ptr = malloc(sizeof(int)); this line will cause a compile time error error: assigning to 'int *' from incompatible type 'void *' so we should write as ptr = (int*)malloc(sizeof(int)); Besides there is a terrible mistake, we discuss this in No.2.

  • No.2 you only malloc sizeof(int) bytes memory, and use it for more than sizeof(int) bytes.

  • No.3 the ptr increased every time our program get input value. But ptr never comes back to when printf begins.

This code may be work or not, as programer often says "this cause undefined behavior". Because we use some memory we didn't malloc.

int val, x;
int *ptr;
int *ptr_origin;
ptr = malloc(sizeof(int));  

ptr_origin = ptr;
do
{
    scanf("%d", &val);
    *ptr = val;
    ptr++;
}while(val < 20);    

ptr = ptr_origin;
for(x=0; x<5; x++)   //Print values *ptr          
{
    printf("ptr[%d]: %d\n", x, *ptr);
    ptr++;
}

And this final version should be work.

int val, x, total, total2;
int *ptr;
int *ptr_origin;
scanf("%d", &total); // specific input value counts
total2 = total;
if (total <= 0)
{
    printf("invalid count\n");
    return 0;
}
ptr = malloc(sizeof(int)*total);  

ptr_origin = ptr;
do
{
    scanf("%d", &val);
    *ptr = val;
    ptr++;
}while(--total > 0);    

ptr = ptr_origin;
for(x=0; x<total2; x++)   //Print values *ptr          
{
    printf("ptr[%d]: %d\n", x, *ptr);
    ptr++;
}

UPDATE: as Iskar Jarak comment, this is C not C++ question. No.1 will not be a problem.

1 Comment

"this line will cause a compile time error error: assigning to 'int *' from incompatible type 'void *'" No. This question is C, not C++.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.