Thread: what is wrong here??? dynamic array of chars

  1. #1
    Registered User
    Join Date
    Jun 2008
    Posts
    23

    what is wrong here??? dynamic array of chars

    I am trying to implement the simple strcat() function by using pointers.
    It states 'Access violation writing location' error, and I don't understand why...
    I also tried to implement it by not using indexes (such as here), but by using
    the pointers themselves (e.g, t++, s++, etc.), and of course, the same problem
    occurs again... see // comment at the line the problem occurs.
    thanks in advance.

    Code:
    #include <iostream>
    using namespace std;
    
    void strcat(char* t, char* s);
    
    void main(){
    	char* t, *s;
    	t=new char[200];
    	s=new char[100];
    	if (t==NULL || s==NULL)
    		exit(1);
    	else
    	{
    		t="Hello world";
    		s="avi";
    		strcat(t,s);
    		cout<<t;
    	}	
    	delete []t;
    	delete []s;
    }
    
    //Ans. 3 (a)
    void strcat(char* t, char* s){
    	int iRead, iWrite;
    	iRead=0;
    	iWrite=0;
    	while (t[iWrite]!='\0')	
    		iWrite++;	
    
    	while (s[iRead]!='\0')
    	{					
    		t[iWrite]=s[iRead];	  //problem is here
    		iRead++;
    		iWrite++;
    	}	
    	t[iWrite]='\0';
    }

  2. #2
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    t is pointing to a constant literal (t="Hello world";). You cannot change these. It would also crash because you're trying to free it with delete.
    Last edited by 39ster; 06-07-2008 at 06:02 AM.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,653
    Not to mention you completely change the point to something new. In other words, you allocated memory is now lost.
    So 1) you can't free it and 2) string literals are const, so you get an access violation trying to modify any of the data and 3) there's not enough space.
    There's a reason why we avoid using C-style strings in C++.
    To copy a string into an allocated buffer, use strcpy.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User
    Join Date
    Jun 2008
    Posts
    23
    Thanks, people...
    Now it is working and I don't understand why (the idea of constant vs. cin... it's stupid)...
    here's the working version...

    Code:
    void main(){
    	char *t, *s;
    	t=new char[200];
    	s=new char[100];
    	if (t==NULL || s==NULL)
    		exit(1);
    	else
    	{
    		cin>>t;     //here's the correction
    		cin>>s;     //here's the correction
    		strcat(t,s);
    		cout<<t;
    	}	
    	delete []t;
    	delete []s;
    }

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,653
    No, this is bad too. It's a C way. It only increases the chance for buffer overruns and stops at whitespace.
    Better to use cin.get, or even better use std::string and std::getline instead.

    You can also do it your old way by doing:
    Code:
    		strcpy(t, "Hello world");
    		strcpy(s, "avi");
    Again, however, I must note that this is insecure, especially in C++ since you do no checking if there's enough room in the buffer.
    The C++ way is much better and easier:
    Code:
    std::string str1 = "Hello world";
    std::string str2 = "avi";
    str1 += str2;
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    Quote Originally Posted by lionheart View Post
    Thanks, people...
    Now it is working and I don't understand why (the idea of constant vs. cin... it's stupid)...
    here's the working version...

    Code:
    void main(){
    	char *t, *s;
    	t=new char[200];
    	s=new char[100];
    	if (t==NULL || s==NULL)
    		exit(1);
    	else
    	{
    		cin>>t;     //here's the correction
    		cin>>s;     //here's the correction
    		strcat(t,s);
    		cout<<t;
    	}	
    	delete []t;
    	delete []s;
    }
    What's the idea of constant vs cin? You can use string literals, you just have to COPY it into the char array using strncpy or in the constructor of the char array.

    Code:
    void main()
    {
        char t[200], s[100];  //why use dynamic allocation?
        strncpy(t, "Hello World", sizeof(t)); //copy "Hello World" to t
        strncpy(s, "avi", sizeof(s));   //Copy "avi" to s
        strcat(t,s);    //call that function you made
        printf("&#37;s\n", t);  //display results
    }
    You may also copy string literals like this:

    Code:
    char t[] = "Hello World"
    It only works in the constructor and the resulting size of the array will only be as long as the string + 1 so you couldnt copy anything else to it
    Last edited by 39ster; 06-07-2008 at 06:43 AM.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,653
    Strncpy has its own quirks, however.
    If the buffer is not large enough to hold the data you copy, it will copy sizeof(t) characters, but it won't put a null char, so you will get a non-null terminated string and therefore C string functions will mostly likely crash the application.
    There's just no safe way of doing it in today's C world without a lot of additional checks.

    Now that I see it, don't use void main:
    http://cpwiki.sourceforge.net/Void_main
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Jun 2008
    Posts
    23
    But I'm using C (and don't even ask why...), and I'm sorry that I didn't let you know of the assumption: the size of 's' cannot be over the physical size of 't'...

    ...and the problem with the constructor is that it is not dynamic (at least for my own purposes)...

    Many thanks of the discussion...

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,653
    OK, I'm confused here.
    I can swear this was in the C++ section some time ago.
    Furthermore, you ARE using C++ with new/delete, cin/cout.
    So which is it here - C or C++?
    If it's C, you should replace new/delete with malloc/free, and cin/cout with fgets/printf,
    and if it's C++, you should probably use std::string and std::getline.

    I also found an additional problem:
    Code:
    	if (t==NULL || s==NULL)
    		exit(1);
    If this condition is true, you never free your allocation buffers.

    Quote Originally Posted by lionheart
    the size of 's' cannot be over the physical size of 't'...
    But even with this argument, even if t is just +1 greater than s, you can still get an overrun. And you're going to make the mistake someday. So it's critical that you make checks to avoid buffer overruns, so it won't come back and bite you one day, somewhere in the code.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Jun 2008
    Posts
    23
    By this:"the size of 's' cannot be over the physical size of 't'..."
    I meant the size of 's + t' cannot go over the physical size of 't'... (sorry again)...

    And I used this thread since it is "c programming" thread...

    Thanks for the if (t==NULL || s==NULL) part... I only noticed it now... I have corrected the mistake

  11. #11
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    I also never check the result of malloc() or new. I dont know if that's good practice or not but generally if malloc or new fails, than you have bigger problems and your whole program is going to fail wether you check it or not.

    EDIT: Unless its for HUGE allocations

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,653
    Well, you're still using C++ code (cin/cout/new/delete).
    So if you're using C, then how come you're using C++ code?

    Quote Originally Posted by 39ster View Post
    I also never check the result of malloc() or new. I dont know if that's good practice or not but generally if malloc or new fails, than you have bigger problems and your whole program is going to fail wether you check it or not.
    EDIT: Unless its for HUGE allocations
    Yes, it's bad practice not to check since if it fails, you may attempt to access an invalid pointer (or in the case of C++, it will throw an exception).
    It's better to fail with some elegant error or try to recover than crash.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    Jun 2008
    Posts
    23
    The correction of the checkup is:
    Code:
    	if (t==NULL && s!=NULL)
    	{
    		delete s;
    		exit(1);
    	}
    	else if (t!=NULL && s==NULL)
    	{
    		delete t;
    		exit (1);
    	}
    	else if (t==NULL && s==NULL)		
    		exit (1);
    Just for being formal...

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,653
    A better way...
    Code:
    int main()
    {
    	char* t = malloc(200);
    	char* s = malloc(100);
    	if (t==NULL || s==NULL)
    		goto Exit;
    	else
    	{
    		strcpy(t, "Hello world");
    		strcpy(s, "avi");
    		strcat(t, s);
    		printf("&#37;s", t);
    	}	
    
    Exit:
    	if (t) free(t);
    	if (s) free(s);
    }
    You still haven't explained why there's C++ in your C code.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Jun 2008
    Posts
    23
    I'm implementing the function and not the void main() part,
    The void main() part is being used only for output sampling...

    I'm using c++ syntax, but in a "c" kind of way... (and don't ask why, I have a deadline and a small project to implement, so I'm correcting what is there to correct, rather than learning all of C++ features and syntax). Maybe in 3-4 months, I'll be sitting here reprogramming the project, but as of now I haven't got the time for being 'politically correct", if you wish...

    I just hope that the function of strcat() works, that's all:
    Code:
    void strcat(char* t, char* s){
    	int iRead, iWrite;
    	iRead=0;
    	iWrite=0;
    	while (t[iWrite]!='\0')	
    		iWrite++;	
    
    	while (s[iRead]!='\0')
    	{					
    		t[iWrite]=s[iRead];	  //problem is here
    		iRead++;
    		iWrite++;
    	}	
    	t[iWrite]='\0';
    }
    Since it does, I have no other problems...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. dynamic array of pointers?
    By baniakjr in forum C++ Programming
    Replies: 3
    Last Post: 12-29-2006, 09:46 AM
  2. Replies: 4
    Last Post: 11-02-2006, 11:41 AM
  3. question about multidimensional arrays
    By richdb in forum C Programming
    Replies: 22
    Last Post: 02-26-2006, 09:51 AM
  4. Merge sort please
    By vasanth in forum C Programming
    Replies: 2
    Last Post: 11-09-2003, 12:09 PM
  5. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM