473,412 Members | 5,385 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,412 software developers and data experts.

Common mistakes that trapped me always!

35
I did C in UNIX environment. These are some of the common mistakes that always trapped me in my work. I need help from you guys to clarify them with me.




1)
Expand|Select|Wrap|Line Numbers
  1. int intArray[5] = {1,2,3,4,5}, i;
  2.  
  3. for(i = 0; i < 5; i ++){
  4.    printf( "%d", *(intArray + i) ); 
  5. }
  6.  
As we know, array name ,intArray is a constant pointer, it always point to the beginning of the array i.e. &intArray[0].

Hence, this is correct. The + operator add i to intArray. This simply means: "POINT TO i th LOCATION BEYOND intArray , which is pointing to the beginning of the intArray and DEREFENCE THE POINTER". intArray remain pointing at the first element in the array.

2)
Expand|Select|Wrap|Line Numbers
  1. int intArray[5] = {1,2,3,4,5}, i;
  2.  
  3. for(i = 0; i < 5; i ++){
  4.    printf( "%d", *(intArray ++) ); 
  5. }
  6.  
This is wrong. The ++ operator is changing the constant pointer , intArray to pointing to the other places, in this case, the next element in the array. In addition, the first iteration of the for loop will print the second element in the array because (intArray ++) makes intArray pointed to the second element in the array and the * dereference the pointer. And when i == 4, the pointer over flow to the end of the array and error occurred here.

3)
Expand|Select|Wrap|Line Numbers
  1. int intArray[5] = {1,2,3,4,5}, i;
  2.  
  3. for(i = 0; i < 5; i ++){
  4.    printf( "%d", *(intArray + 1) ); 
  5. }
  6.  
I am not sure whether this is correct or wrong. In my observation, it has the same behavior as 2).

4)
Expand|Select|Wrap|Line Numbers
  1. char *a = "Hello";
  2.  
  3. *(a + 1) = 'a';
  4.  
The above statement is correct but the result is undefined cause ANSI C doesn't prohibit us to modify a string literal accessed via a character pointer. However, we are not advice to modify string in this manner, but can we modify the character pointer? I mean can we assign another address to a and make a point to other place. If so, how about the string literal it was originally pointed to? lose reference? Is this considered a memory leak in C ?

5)
Expand|Select|Wrap|Line Numbers
  1. char *b ;
  2.  
  3. b = malloc(5 * sizeof(char));
  4.  
  5. b = "hello";
  6.  
Compare with 4), i am confused. Why do we need malloc() at the first place since we can initialize a character pointer to point to a string literal? In 4), we could use "a" directly instead of malloc it , why? I have tried to assign a string to "b" WITHOUT malloc it, but encountered run time error i.e. core dump. Since we malloc b, so we cannot change the value of b ? If we changed it, we lose reference to the memory slots where it was originally pointed to, thus memory is leaking, am i correct? Provided we free b before modifying b.

4) and 5), i am not very sure what is the logic behind them.

I always trapped by these mistake and slowing down my work. : (
Dec 26 '07 #1
7 2352
oler1s
671 Expert 512MB
It's not entirely clear what you are thinking, because of the confusion in your own statements. I'll comment on what I think you said.

Q1:
Referring to intArray is syntactically equivalent to referring to &intArray[0]. Hence, you can use pointer arithmetic on it. intArray + 1 gets you a pointer to the second element in the array (a pointer to intArray[1]). Not sure how dereferencing comes into the picture, but your grammar with the word "dereference" didn't resolve to anything meaningful.

Q2:
Yes, what you did wouldn't work. But I thought about it for a moment and wanted to clarify. You can't do intArray++, right, because intArray can't be set to something else. But you can do:

Expand|Select|Wrap|Line Numbers
  1. int *p = intArray;
  2. int c = *p++;
  3.  
Now, where am I going with this? Because you might see code like:

Expand|Select|Wrap|Line Numbers
  1. void my_strcpy(char *dest, char *source)
  2. {
  3.     .
  4.     .
  5.     *dest++ = *source++;
  6.     .
  7. }
  8.  
or something along those lines. And it works. Why? Because, remember that when passing something into a function, a copy is made. In this case, if you pass in an array to a function, the function has a pointer to that array. But it isn't the array variable itself. It's a local function pointer to the array you passed in.

Q3:

It's valid. intArray is not being modified. Only i is.

Q4:

The code is not correct. char *a is not the same as char a[]. a[] is an array. *a is a pointer. "Hello" is a constant string literal that a is set to point to. That means you can't modify the contents of that string. So you have a pointing to a constant string. You can't refer to part of that string and change it to something else, because you don't have an array.

If you had an array, you could always use pointer notation to modify it. But you need an array storing the string, not a string literal. Do you get the difference?

Q5:

Now that you know that Q4 is wrong, how would you get a block of memory you can modify? Either statically declare an array. Or dynamically allocate memory for it using malloc. Unfortunately, the above code is also bad. Here's why. char *b is a pointer. b = malloc(...) assigns b to a memory block that is dynamically allocated. Then b = "Hello" assigns b to another memory location that contains the literal string "Hello".

Let me be clear about this, b = "Hello" does not copy the string.

Feel free to follow up with clarifying questions.

You may want to read the C-FAQ: http://c-faq.com/index.html. I will ask you to read section 6 at the very least before posting further questions. Section 8 as well.
Dec 26 '07 #2
primeSo
35
Thank you for the site, it has cleared most of my doubt. : ) . Let me clarify again with i have understand so far.

1)
Expand|Select|Wrap|Line Numbers
  1. int intArray[5] = {1,2,3,4,5}, i;
  2.  
  3. for(i = 0; i < 5; i ++){
  4.    printf( "%d", *(intArray + i) ); 
  5. }
  6.  
Result of these statements: 12345.
*(intArray + i) == intArray[i], I am pretty sure with this.

2)
Expand|Select|Wrap|Line Numbers
  1. int intArray[5] = {1,2,3,4,5}, i;
  2.  
  3. for(i = 0; i < 5; i ++){
  4.    printf( "%d", *(intArray ++) ); 
  5. }
  6.  
Let's do some desk check.
When i = 0, print: 2
i = 1, print: 3
i = 2, print: 4
i = 3, print: 5
i = 4, print: undefined. array overflow (error)

++ ( +1) move the pointer beyond the boundary of the array. correct ?

3)
Expand|Select|Wrap|Line Numbers
  1. int intArray[5] = {1,2,3,4,5}, i;
  2.  
  3. for(i = 0; i < 5; i ++){
  4.    printf( "%d", *(intArray + 1) ); 
  5. }
  6.  
Result from these statements: 22222.

Conclusion:
intArray++ move intArray forward to point to the next object (POSITION OF intArray CHANGED) ) while intArray + 1 doesn't move the pointer, (intArray REMAIN THE SAME POSITION), am i correct ?

4)
Expand|Select|Wrap|Line Numbers
  1. char *a = "Hello";
  2.  
  3. *(a + 1) = 'a';
  4.  
We shouldn't modify a CONSTANT string literal with any means. In addition,do a and "Hello" both are constant? We shouldn't modify any of them?

5)
Expand|Select|Wrap|Line Numbers
  1. char *b ;
  2.  
  3. b = malloc(5 * sizeof(char));
  4.  
  5. b = "hello";
  6.  
We can't use assignment operator ( = ) when assigning string, use strcpy() instead. This is my mistake, haha.

Conclusion:
We can INITIALIZE a pointer to character with char *a = "Hello"; But this is NOT ASSIGNMENT, it simply means: a is a character pointer pointing to the beginning of a chunk of memories and the memories has no name, in this case 5 bytes + 1 null character. And both of them are CONSTANT.

Except the above mentioned situation, any other character pointer must be malloc-ed if we want them to point to a specify unnamed memory location in the machine to store some character value, ie strings.

Thank you.
Dec 27 '07 #3
primeSo
35
Array name is a constant pointer. So, how can we do pointer arithmetic on array name like intArray++ at the first place? This statement is equivalent to intArray += 1.
An array name is ``constant'' in that it cannot be assigned to

Source: http://c-faq.com/aryptr/constptr.htm
What does the "assigned" meant? We cannot change the value contained by array name, am i correct ? IT ALWAYS POINTS TO THE FIRST ELEMENT IN THE ARRAY. but how could intArray++ works at the first place? it is changing the value of intArray.
Dec 27 '07 #4
weaknessforcats
9,208 Expert Mod 8TB
Expand|Select|Wrap|Line Numbers
  1. int intArray[5] = {1,2,3,4,5}, i;
  2.  
  3. for(i = 0; i < 5; i ++){
  4.    printf( "%d", *(intArray ++) );     <<<<<<<<<<<<<<
  5. }
  6.  
Please ask questions only about code that compiles.
Dec 27 '07 #5
oler1s
671 Expert 512MB
So on your clarifications:

Q1: Yes, that's right. I think you have the idea about pointer arithmetic vs. array indexing.

Q2: NO! You had the right idea before, and now you have it wrong. You can't change the pointer intArray itself. If you want to increment a pointer, it needs to be copy of intArray, not intArray itself.

Q3: Yes, intArray + 1 never changes as both intArray and 1 always remain the same...

Q4: Yes. You can't modify that literal. "Hello" isn't being stored in an array. All you have is a literal and a pointer to it.

I don't believe a is constant. You would have to say something like const char *a = "Hello".

I don't know whether or not even if you could, it's OK for you to point a somewhere else. I can't give you a confident answer. I would have to go through various documentation to answer with certainty.

Q5: Yes, the = sign does not copy a string. You need to manually walk through the string, copying each character by character. That's what strcpy does for you.

A char pointer is just that. You can point it to a literal, a dynamically (malloced) allocated memory block of chars, or you can set it equal to another pointer.

Char pointers test your knowledge of pointers. Fundamentally, you need to be clear on the difference between a pointer and an array.
Dec 27 '07 #6
primeSo
35
Expand|Select|Wrap|Line Numbers
  1. int intArray[5] = {1,2,3,4,5}, i;
  2.  
  3. for(i = 0; i < 5; i ++){
  4.    printf( "%d", *(intArray ++) );     <<<<<<<<<<<<<<
  5. }
  6.  
Please ask questions only about code that compiles.
Hm... i am sorry. Don't get what you mean. : )
Dec 27 '07 #7
primeSo
35
Q2: NO! You had the right idea before, and now you have it wrong. You can't change the pointer intArray itself. If you want to increment a pointer, it needs to be copy of intArray, not intArray itself.
haha, i think i am almost there. thank you. I always forgotten the concept of "a copy of the actual parameter, NOT the actual parameter itself". Thank you.

Just one more point to go, let's say those statements in my example are being done in one main(), i didn't so any function calling, then intArray++ is totally wrong. My GCC compiler complainted "Wrong Type Of Argument to Increment". : )

intArray++ can only be done when i call another function to process the array. Thank you. I got it now. *( intArray ++) would not overflow the array but *( ++ intArray) would do.

10s~
Dec 27 '07 #8

Sign in to post your reply or Sign up for a free account.

Similar topics

15
by: Jim | last post by:
This is probably a common question - What is the best CSS editor? I'm an old HTML dinosaur that just getting into CSS. My HTML editor from way back is Homesite. They (Macromedia) tout Topstyle Pro...
3
by: Bishfish | last post by:
I have an XML document containing 400+ quotations, in the format: quotes qtnum title author comment quotes ...400+ more XML file size 156Kb
3
by: mitsura | last post by:
Hi, I have included a small listing. The test program opens a panel and show a bitmap. What I want is to when the mouse is over the bitmap panel, I want to trap the left mouse click. The...
13
by: TC | last post by:
Folks Is there >>ANY<< way to get the actual text of an error that is trapped by the Form_Error event? I mean actual text like: "duplicate record in table XYZ", not template text like:...
2
by: Darrell Wesley | last post by:
When I place a Tab control on a form with one or more TabPages and click inside one of the pages and then click on a tab the mouse cursor gets trapped inside the tab control until I click on...
2
by: martintillbrook | last post by:
I am using the simple mail() fucntion in a php script but the emails that are being generated and being trapped by Microsoft Exchange server 2003 Inteligent message filter as having an SCL rating...
56
by: valentin tihomirov | last post by:
{ int i = 2; } int i = 1; There is no 'i' defined in the 'parent' context from the moment of declaration on. So what is the problem? They tell us they pursue language simplicity. The rule "do...
10
by: r035198x | last post by:
There are a lot of common C mistakes. I have put together the ones I consider to be the silliest made by C programmers. These are usually the source of the popular C programming tears and remembering...
6
Markus
by: Markus | last post by:
Things to discuss: Headers What are they? What does PHP have to do with headers? Why can they only be sent before any output? Common causes
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.