char pointers and scanf()

Hello. More questions about pointers coming:

If I have the following code:


char * userName;
printf("%s", "Enter your name: ");
scanf("%s", userName);
printf("%s", userName);


This codes asks the user for his/her name and reads the input, then it prints the name to output. However, with the code above, I get the debugger after I enter my name and press Enter.

I'm aware that if I changed the first line from a char pointer to a char array then this code would work fine -- but I'd like to understand why this is the case.

I'm sure it's possible that some concept related to the cause of this problem has been covered in one of my previous posts on pointers, but I skimmed through them and couldn't find anything that I could recognize as applicable (although I'm sure it was there somewhere). Could anyone please help me understand why scanf() doesn't work with the char pointer -- why it would work fine with a character array and not with the character pointer?

Thank you for your help.

MacBook, Mac OS X (10.5.8)

Posted on Oct 8, 2009 1:34 AM

Reply
29 replies

Oct 8, 2009 3:33 AM in response to Tron55555


char * userName; // Line 1 - reserve 4 bytes for the address of a char
scanf("%s", userName); // Line 2 - starting at the address userName points
// to, write bytes to consecutive addresses
// until the user types <Enter>

Suppose the address stored in userName is X, and the user types Tron55555:
X->[T] X+1->[r] X+2->[o] X+3->[n] X+4->[5] X+5->[5] X+6->[5] X+7->[5] X+8->[5]


Is anything wrong with this picture? Maybe userName was even initialized to zero. Now at least we know where your name will be written in memory. Do you think the system is ok with the memory locations 0000 through 0008 containing (the ASCII code numbers for) tron55555? How bout if userName wasn't initialized. Suppose it contained the address 8720. Would the memory locations from 8720 through 8728 be a good place to write tron55555?

Think on this. Think about what the above code does, and decide if you want that in your program.
- Ray

Oct 8, 2009 4:48 AM in response to RayNewbie

Thanks for the reply, Ray.

Think on this. Think about what the above code does, and decide if you want that in your program.


No, I don't want this in my program -- I've used a character array instead of a character pointer to hold userName -- I just want to understand why the character pointer doesn't work.

Would the memory locations from 8720 through 8728 be a good place to write tron55555?


Sounds like the answer is no, but I don't know why. Sorry - I'm just really uninformed when it comes to this type of thing (this type of thing being programming in general, I guess, but memory and what not in particular). I'd like to get to a point where I can figure this stuff out on my own and not have to keep asking so many questions, but I'm just not there yet. Anyways, I can tell your making a good point here, but it's going right over my head. Can you help me understand what you were trying to say in your post? What is it that would be bad about writing "tron55555" to those locations?

Your explanation of each statement using the comments in the code sample at the top of your post was very helpful to me in visualizing how this bit of code works. I'm still unclear, though, on why exactly I get a runtime error after I type in my name and hit Enter if I use a character pointer to hold userName. What it is specifically about character pointers that causes this to be a problem with them and not with character arrays? I mean, this works fine:


char userName[32];
printf("%s", "Enter your name: ");
scanf("%s", userName);


but this does not:


char * userName;
printf("%s", "Enter your name: ");
scanf("%s", userName);


In the first case, userName is an array of up to 32 characters, and the identifier "userName" is a pointer to the first character in that array, so when you use it in the scanf() statement, it works fine, because you are telling scanf() to take the string of characters entered by the user, and place it in the array of characters called userName. Is this right?

In the second case, however, I'm a bit less clear on how it all works. Here, "userName" is a pointer to a single character (but this single character can be the first character in a series of consecutive memory addresses, which combine to store a string of characters, right?). So, what is the problem in telling scanf() to take the string of characters enetred by the user and to place it in those consecutive memory addresses?

Any further help or input in general with this topic is greatly appreciated. Thank you!

-- Tron

Oct 8, 2009 6:57 AM in response to Tron55555


char Username[32];
char *pUsername = Username;
scanf("%s", pUsername);

would be OK, as pUsername has been initialized.

char *pUsername;
scanf("%s", pUsername);

is not OK, because we do not control where pUsername points.

This is like calling for Pizza delivery, and then not telling the pizza place where you live. Only in this case, the pizza delivery guy still makes the pizza, and delivers it to some address written on the bathroom wall. You don't get your pizza, and they still charge your credit card.

OK, stupid analogy. Depending on the function you are calling, you must provide the storage for the values it returns. scanf("%s") requires a pointer to valid storage. Not just a pointer. A pointer is useless unless it points to something useful. An uninitialized pointer is like an address book without any names in it. It has potential, but otherwise useless (except I guess you could use it to level a wabbling table).

Computers are stupid. They only do what you tell them to do. And you have to tell them a lot, especially when working at the C level of programming. The good news about C, is that it can give you precise control. The bad news is, you have to be careful what you ask C to do, as it will do what you ask, even if you ask it to self destruct.

Oct 8, 2009 7:08 AM in response to Tron55555

Tron55555 wrote:
In the second case, however, I'm a bit less clear on how it all works. Here, "userName" is a pointer to a single character (but this single character can be the first character in a series of consecutive memory addresses, which combine to store a string of characters, right?). So, what is the problem in telling scanf() to take the string of characters enetred by the user and to place it in those consecutive memory addresses?


A pointer must point somewhere. When you have a character array, that character array is the "somewhere" and the array variable can be treated "as if" it were a pointer. If you have a true pointer, it must be made to point somewhere before you can use it. It can point to a character array, some data allocated via malloc, or some other value.

All of the following are valid uses for a pointer. (Not all of them are advisable though).

char a[100];
char * p = & a[0];
char * m = (char *)malloc(100);
long l = 4;
char * dontusethis = (char *) & l;


The last one is particularly interesting. Not only does a pointer have to point "somewhere", that "somewhere" must be big enough for what you want to use it for. If you have an array of size 32, you can put at most 31 characters in it (because you need the null character to). In the last example, "dontusethis" is a valid string pointer but can only hold a string with up to 3 characters. It isn't very useful, but, as a pointer, it is just as valid as any other pointer.

Oct 9, 2009 12:15 AM in response to etresoft

Thanks, Bob -- your post was very enlightening. I'm sure I'll still have plenty of questions regarding pointers in the future, but that at least clears up for me why the uninitialized char pointer didn't work with scanf(). Thank you for that.

Etresoft -- your post was very helpful as well. I have a question about something you said early on it in.

A pointer must point somewhere. When you have a character array, that character array is the "somewhere" and the array variable can be treated "as if"


Can you expand on this a bit? Why is that character array the "somewhere"? Wouldn't the array have the same problem if it was uninitialized that the char pointer had, or is there something different about the way char arrays are created internally that makes this not true?

Thanks, guys.

Oct 9, 2009 6:52 AM in response to Tron55555

Can you expand on this a bit? Why is that character array the "somewhere"? Wouldn't the array have the same problem if it was uninitialized that the char pointer had, or is there something different about the way char arrays are created internally that makes this not true?

A Character array is a container that can hold things. You can put stuff in a container and it will hold that stuff until you want it again.

As for being uninitialized, that just means do not look at the contents of the container (character array) until after you put something useful in it, otherwise it contains junk as well.

Since a pointer is only good if it is pointing at something, an uninitialized pointer is dangerous. Like gun safety: "always know where you are pointing it" (and never point it at your foot 🙂 ).

A pointer can point to different things. Its value is that what it points at can be changed, but the program only need to remember the name of the pointer. Pointers are useful in that you can pass the address of something really huge to a function, instead of physically copying the huge something to function local storage, having the function modfiy its local storage, and then copy the huge something back so the caller can see the change. Rather the pointer is passed, the function works through the pointer, and the caller sees the results when the function returns, without excessive argument copying.

Arrays of any kind, when passed to a function ALWAYS have the address of the array passed to the function.

An array that is assigned to a pointer will always give the pointer the array's address.

In many cases where you can use an array, you can use an initialized pointer. However, pointers change what they point at. You can perform "Pointer Math" on a pointer. Pointers are extremely flexible, but they do not hold stuff. They only point at stuff.

Oct 9, 2009 7:31 AM in response to BobHarris

That's all good info, Bob. I am still curious, though, about the character arrays working for the scanf() function. Thanks to yours and etresoft's last posts, I understand now why an uninitialized char pointer does not work with the scanf() function. As you said, it is because a pointer must point to something useful. So, based on that, I guess what I'm asking is why does a char array work even if it's not initialized? Shouldn't the uninitialized char array have the same problem with the scanf() function that the uninitialized char pointer has? Does an array always point to something useful, even if it's uninitialized? Or is there a different reason? What's the reason that I can declare a char array and not initialize it and it works fine with scanf(), whereas if I declare a char pointer and not initialize it it does not work? Thanks for your time.

Oct 9, 2009 7:41 AM in response to Tron55555

Tron55555 wrote:
Wouldn't the array have the same problem if it was uninitialized that the char pointer had, or is there something different about the way char arrays are created internally that makes this not true?


It sounds like you are confusing "allocation" with "initialization". They are very different. For example, the typical Cocoa object creation sequence is:

MyObject * obj = [[MyObject alloc] init];

Here, the first thing that happens is that the memory is allocated. Then, the allocated memory is initialized. Allocation is where your process asks the OS for some additional memory to use. Initialization is where the process assigns initial, valid values to the allocated memory.

When you create a character array on the stack via:

char array[100];

The array is allocated on the stack, but not initialized. Since arrays are just POD, not objects, they don't really need to be initialized. You can just start writing data into them. You could read data too, but it would be garbage.

A pointer is the same, you can assign a value to the pointer itself. That will make it point somewhere. But you can't use the pointer until you do so. Because an uninitialized pointer could reference memory anywhere, including inaccessible memory, it isn't as safe as an array. You can't even safely read the data from a pointer that hasn't been assigned a valid value. Where it points to is garbage and if you dereference that garbage (even to read it), you could likely get a bus error.

I think it helps a great deal to have had a wacky professor years ago who insisted we do everything in assembler. That really helps to understand these low level details.

Oct 9, 2009 8:39 AM in response to etresoft

Okay -- two questions:

1.) The reason, as you said, that an uninitialized array will work with a function like scanf() is because arrays are "plain old data" and not objects, so they don't really need to be initialized. I'm assuming that means, therefore, that pointers, unlike arrays, are objects and not POD, which is why they do not work with a function like scanf() when uninitialized. Is this correct?

2.) You said you can't use a pointer until you assign a value to the pointer. By this I assume you mean that you can't use a pointer until you've written a statement like:


char * pChar;
pChar = &charVar


or some other statement that assigns an address to the pointer. Until you've done that, you can't use it -- that's what you mean, right? I understand this to be the case, for the most part, but here's what confuses me about that -- consider the following code:


char * pChar = "Tron";


Here you are using the pointer before you've assigned an address to it, right? With character pointers, you seem to be able to use them before initializing them. Is this an exception to your rule, or does it just appear to be (to me at least) and there's a reason that it's actually not?

Thanks again for your help.

Oct 9, 2009 8:58 AM in response to Tron55555

Tron55555 wrote:
1.) The reason, as you said, that an uninitialized array will work with a function like scanf() is because arrays are "plain old data" and not objects, so they don't really need to be initialized. I'm assuming that means, therefore, that pointers, unlike arrays, are objects and not POD, which is why they do not work with a function like scanf() when uninitialized. Is this correct?


No, sorry 🙂

Pointer are plain 'ole data, but still a bit special - over and above objects. In C++, objects can be both on the stack and on the help, so all the same pointer considerations apply, even with objects. So, if you have a pointer to an object, the object must be allocated and initialized, and the pointer must be initialized as well - to point to the object.

A pointer is POD just because of the fact that it is probably the same size as a long data type. Most pointers reside on the stack just like a regular int, long, or double. Since they are already on the stack, they don't need to be allocated, but must be initialized before they can be used.

If you read an uninitialized int, you just get a garbage value. When you read a pointer, you are probably dereferencing it and, depending on the pointer type, could cause the CPU to choke and abort your program. That is the big difference.

For example, an integer must be on a word boundary in memory. An uninitialized pointer could have an odd address (like the value 3). That pointer could point to an integer. The CPU wouldn't like it if you tried to get the integer value that such a pointer references.

here's what confuses me about that -- consider the following code:


char * pChar = "Tron";


Here you are using the pointer before you've assigned an address to it, right? With character pointers like this, you seem to be able to use them before initializing them. Is this an exception to your rule, or does it just appear to be (to me at least) and there's a reason that it's actually not?


No, when you allocate a pointer on the stack (or any value) and do an assignment before the semicolon, that is an initialization. In this case, you are allocating your pointer on the stack and initializing it to the address of a string literal in memory.

This is a big deal in C++. Such a line of code would call only a constructor, not the assignment operator. It is important also because if you didn't do the initialization this way, the object would still have to be initialized with a default constructor. At best this is wasteful, at worse, it could be a serious logic error.

It isn't such a big deal in Objective-C because most objects can be constructed with just "init" and because complex constructors aren't used as much.

It is even less of a big deal in C, but the logic is still the same.

Oct 9, 2009 12:04 PM in response to Tron55555

So, based on that, I guess what I'm asking is why does a char array work even if it's not initialized? Shouldn't the uninitialized char array have the same problem with the scanf() function that the uninitialized char pointer has? Does an array always point to something useful, even if it's uninitialized? Or is there a different reason? What's the reason that I can declare a char array and not initialize it and it works fine with scanf(), whereas if I declare a char pointer and not initialize it it does not work?

Because the character array "IS" the "Something"

scanf() wants a character array to store stuff into. scanf() assumes that the address passed to scanf() that is associated with the "%s" field is a character array. It is part of the rules set forth on the scanf() man page.

And scanf() is actually providing the initialization of the character array. Before scanf() does its thing, there was nothing useful in character array, so looking at it before the scanf() would not be a very productive thing.

NOTE: initializing a character array can be done a gazillion ways. Mentioning scanf() in this discussion is only because it is your topic title.

Another bad analogy. I have 2 bottles. In one bottle is a note, that says: "The other bottle has the water you want". In the other bottle is water.

The 1st bottle is a pointer. The 2nd bottle actually holds something.

I can take is a step further. A bottle has a note: "The left most bottle on the bottom shelf is the 1st bottle of an array, and each adjacent bottle contains fresh water, until you find an empty bottle and then any bottle following that has contaminated water. There you have a character array with a nul terminated string in it.

I have a function GetWater(). I copy the address of the bottle array into a register (left most bottle on bottom shelf), and then I call GetWater(). GetWater takes the address from the register, and dutifully fills each bottle starting with the "left most bottle on the bottom shelf" until GetWater() runs out of water (since GetWater() only has a gallon jugg, this happens before we use up the bottles on the bottom shelf. Before GetWater() returns, it empties out the next bottle it would have filled, as marker indicating where the fresh water stops. We now have described scanf("%s", char_array).

If we had stored "left most bottle on bottom shelf" in our bottle with the note inside, we could have called GetWater() by first copying the contents of the note into a register, and then making the call. The end result would have been the same, since our bottle with the note inside said "left most bottle on bottom shelf". GetWater() would not have known, nor cared where we got the address we put into the calling register.

NOTE: My analogy is going to start to break down in a moment, but I'll push on anyway 🙂

Now instead of a few bottles, we have millions/billions of bottles, each of which can hold notes, water, peas (addresses, characters, numbers). That is your computers memory.

Of course I used a single bottle to store an address, where as in your computer the bottles would be considered bytes, and it would take several bytes to store an address. I told you my analogy would break down.

Oct 9, 2009 7:12 PM in response to Tron55555

RayNewbie wrote:
Would the memory locations from 8720 through 8728 be a good place to write tron55555?

Tron55555 wrote:
Sounds like the answer is no, but I don't know why. ...
So, what is the problem in telling scanf() to take the string of characters enetred by the user and to place it in those consecutive memory addresses?

Hey Tron -
I didn't mean to ignore your followup, in fact I've looked at the above several times in the past couple days, wondering how I could possibly get the missing concept across. Meanwhile I've carefully read the excellent explanations from Bob Harris and Et. My favorite is the pizza analogy!

But this effort has also been very frustrating for me, since as I wrote previously, this kind of discussion needs two people in the same room with a white board (and maybe a pizza as well).

Basically you're asking, "Why can't I store Tron55555 at the 9 consecutive memory addresses which start with the address that happens to be stored in userName?" What's different between these nine bytes and the 9 bytes that begin with the first address of userArray\[32\]??

I'll tell you the answer, but when you ask why it matters, I just don't know where to go:

The answer is that the address stored in userName is random, and more importantly _Not Allocated_ for the purpose of storing new data. This means that storing Tron55555 at that starting address is either going to raise an exception because that address is _outside the memory allowed for your program_, or else that address already _contains information your program needs_,

The concept goes to the very nature of what's known as "A stored program digital computer". A program always requires two things: Code and Data. When your program is loaded from disk, both the code and the data are written to memory. Where in memory? In a modern computer, that's decided by the "Operating System" (OS). Since many programs may be loaded into memory at the same time, the OS must assign specific blocks of memory to each program. When a program attempts to access memory outside this range, it's terminated with an exception.

But within the blocks of memory allocated to your program, there are also strict rules. Suppose the code for your program is stored in the memory block starting at 7000 and ending at 9000. What happens when you write Tron55555 right in the middle of that code block at 8720 through 8728?

Answer: The code that used to be in those bytes is overwritten by the chars of Tron55555. When the program gets to that code, the computer will read an instruction that's nonsense, and terminate the program.

Actually, in a modern computer, the memory containing your program's code will be marked "readonly", so the program will never get a chance to overwrite its own code. But the attempt will still terminate the program.

So what happens if 8720 falls within the Data section of your program? Well overwriting data doesn't do your program much good either. Maybe 8720 is the address where userArray\[32\], begins. If that array contained the characters "RayNewbie", it now contains "Tron55555". Of course that might be a change for the better. But in general, random changes to your data tend to be undesirable.

That said, I don't expect you to grok the concept of memory maps and memory management from what I wrote. These are big topics which are far more important than any one language or machine. The questions you've raised in this thread go to the basics of "What is a Computer?" and "How do Computers Work".

As much as I love to teach in this forum, and as much as I hope this forum is a place where people feel comfortable asking basic questions, if you want to understand these concepts, it's now time for you to enroll in a class. You need the basics of what a computer actually is, and then, if you really want to understand what you're asking in this thread, you will find the answer in a class on Assembly Language.

You're going to make everyone crazy if you keep nibbling at these concepts, one C statement at a time. These threads never really end, though mercifully you've chosen to close a few after 20 or 30 responses. If you keep flailing away, I and everyone else here will try our best, but you're wasting your own time by trying to deal with this kind of question in a forum.

Most students will just accept that char*userName; creates a variable that doesn't point to a legal allocation. But you want to know "Why? And what's a legal allocation, anyway??". That's no longer a C question. That's a basic question about how computer's work. I think you're going to be a great programmer if you keep wanting to know how everything works at a low level. But you'll never get that from a forum. And mining it out of books isn't the way to learn it either. When you write assembly code that's graded by a live instructor and discussed with your colleagues, everything you're asking here and much more will suddenly be easy for you.

\- Ray

Oct 10, 2009 1:31 AM in response to RayNewbie

RayNewb:

That said, I don't expect you to grok the concept of memory maps and memory management from what I wrote. These are big topics which are far more important than any one language or machine. The questions you've raised in this thread go to the basics of "What is a Computer?" and "How do Computers Work".
As much as I love to teach in this forum, and as much as I hope this forum is a place where people feel comfortable asking basic questions, if you want to understand these concepts, it's now time for you to enroll in a class. You need the basics of what a computer actually is, and then, if you really want to understand what you're asking in this thread, you will find the answer in a class on Assembly Language.
You're going to make everyone crazy if you keep nibbling at these concepts, one C statement at a time. These threads never really end, though mercifully you've chosen to close a few after 20 or 30 responses. If you keep flailing away, I and everyone else here will try our best, but you're wasting your own time by trying to deal with this kind of question in a forum.


You know it's funny you said this, because I just came to this conclusion myself over the the course of this thread. You mentioned that most students will simply accept that this works like this and that works like that and what not -- I've never been like that, as I'm sure you've been able to tell. I always have to keep digging until I'm confident that I've reach a point where there is nothing else to be found by continuing, and you're right -- that's not fair to all you guys around here -- that's not what you're here for, and I get that.

The thing is, I've got all these books on C, right, and they start teaching a concept on pointers or something and, naturally, it leaves some question open, and given my nature, I can't rightfully continue until I know the answer to that question. Of course, that question raises another, and then another, and another -- each deeper into the core of things until I reach a point where, as you said, I'm not even really learning C any more. I think it just took me digging this far down to realize that.

Anyways, I was about to say this in my post anyways, and reading what you said was a timely confirmation of that, so -- I will try to stick to questions that are either basic or, if not, then at least specific to something, instead of asking for general information on deeper issues such as these. I always feel like I have to keep learning until I know everything about a certain something, and right now that something is C, so, in that sense, telling me that what we are talking about is beyond C provided good closure for me in not worrying about the details of this stuff.

As far as the classes go, I think you're right on. I hadn't even considered that as an option. To me, learning something means cracking open a library of books on the subject and teaching myself -- even with college classes, I always take online courses where I end up doing the bulk of the work myself out of a text book.

Anyways, with all that aside, thanks for responding, Ray. I'm sorry to have had you thinking on this one that much. I guess I'm so novice with this stuff that part of me figures that this is just child's play for you guys, but I don't want any unreasonable amount of time spent answering my questions, so if a question is beyond any reasonable boundaries in the future, if it's not something that can reasonably be answered on these forums, then just tell me so -- I won't be offended.

In terms of pointers/arrays and scanf(), your post was definitely helpful to me -- in particular the paragraph that started with "the answer is that the address stored in userName is random..." I think your post (in combination with the other guys') gave me enough of an answer for me to rest in peace on this one. 🙂 Thanks, Ray.

Bob:

I like your analogies, and they aren't bad ones at all. The concept of arrays and pointers in general is one that I actually do understand, but the analogy certainly didn't hurt to help cement those concepts into place, and it was particularly helpful in applying those concepts to the issue at hand (with scanf), so thank you for that.

The paragraph beginning with "scanf() wants a character array to store stuff into" was very enlightening in how simple it was. That may have been the general answer I was looking for. Thanks for your posts, Bob.

etresoft:

Thanks for the explanations. The only question left that I would have is, given your explanation about how anything before the semicolon is an initialization, then what about if you put the assignment on a separate line, like:


char * pChar;
pChar = "Tron";


You mentioned, though, the "address of a string literal in memory" and that made me remember something I read, that string literals are taken and stored at their own address (or something like that), so when you assign a string literal to something you are actually assigning the address of a string literal to it, so that might answer my question. In either case, I'm not worried about it, I'm going to close this thread out, but thank you for all your responses in this thread -- they were very helpful.

Oct 10, 2009 1:52 PM in response to Tron55555

Tron55555 wrote:
Thanks for the explanations. The only question left that I would have is, given your explanation about how anything before the semicolon is an initialization, then what about if you put the assignment on a separate line, like:


char * pChar;
pChar = "Tron";


Then you have two actions. You are allocating the pointer, but not initializing it. Then you assign a value to the pointer. It is more wasteful in lines of code than anything else. One of the things that keeps Objective-C simple is that objects are always pointers. Pointers are simple data types and very easy to deal with. The above two statements in C++ would be an entirely different discussion.

Oct 10, 2009 2:20 PM in response to RayNewbie

RayNewbie wrote:
But this effort has also been very frustrating for me, since as I wrote previously, this kind of discussion needs two people in the same room with a white board (and maybe a pizza as well).


When is that going to happen? You are glossing over a huge issue. How does anyone learn programming? Not in a big lecture class. Not on the job - no one is going to go over details like this at work. (Not really true, but I'm trying to make a bigger point). Programmers are expected to learn how to program on their own. There is a reason why modern software is so bad, bloated, and buggy - no one knows how to do it! The software development industry has serious problems and training new programmers is one of the biggest.

As much as I love to teach in this forum, and as much as I hope this forum is a place where people feel comfortable asking basic questions, if you want to understand these concepts, it's now time for you to enroll in a class. You need the basics of what a computer actually is, and then, if you really want to understand what you're asking in this thread, you will find the answer in a class on Assembly Language.


I don't disagree with anything you've said here, but it is definitely easier said than done. Schools don't teach assembly anymore. They barely even teach programming. Programming is a "skill" that students are expected to "pick up on their own" in most computer science programs.

You're going to make everyone crazy if you keep nibbling at these concepts, one C statement at a time. These threads never really end, though mercifully you've chosen to close a few after 20 or 30 responses. If you keep flailing away, I and everyone else here will try our best, but you're wasting your own time by trying to deal with this kind of question in a forum.


I much prefer answering Tron's questions than the old "I spilled soda pop in my Macbook Pro and now it won't turn on!"

Most students will just accept that char*userName; creates a variable that doesn't point to a legal allocation. But you want to know "Why? And what's a legal allocation, anyway??". That's no longer a C question. That's a basic question about how computer's work. I think you're going to be a great programmer if you keep wanting to know how everything works at a low level. But you'll never get that from a forum. And mining it out of books isn't the way to learn it either. When you write assembly code that's graded by a live instructor and discussed with your colleagues, everything you're asking here and much more will suddenly be easy for you.


Unfortunately, that last part is never going to happen either:)

I happen to think that this forum is one of the better ones. There are certainly some good computer science programs, some of which may even have assembly classes, but there are a whole lot of bad ones too. Don't expect to learn anything about memory allocation in a C# class.

The squeaky wheel gets the grease. As long as you get good answers here in the forums, keep asking questions. If Ray or I get tired of answering, that will just give someone else a chance to answer. Try to find a good computer science program to enroll in too. You will learn a lot there. However, you will still have questions that your colleagues can't answer, your TA doesn't understand, and your professor doesn't have time to answer.

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

char pointers and scanf()

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.