Thread: Bizarre array overwriting

  1. #1
    Registered User
    Join Date
    May 2010
    Location
    San Jose, California, United States
    Posts
    22

    Question Bizarre string overwriting

    Ok, so I'm working on this assignment which is supposed to somewhat imitate Unix's cp command (with files "foo.txt" and "bar.txt"). It's been going good up until this section:
    Code:
    char* getPath(char* path, int level)
    {	char** dirList = breakdown(path);
    	if(a==1){	//if path string was only the filename, prepend cwd path
    		char tmp[strlen(path)];
    		strcpy(tmp,path);
    		char* newPath = getcwd(buf,128);
    		strcat(newPath, "/");
    		strcat(newPath, path);
    		return newPath;
    	}
    	path = "";
    	for(int i=0;i<a-level;i++){
    		strcat(path, dirList[i]);
    		strcat(path, "/");
    	}
    	return path;
    }
    
    void copy(char* srcFile, char* destFile)
    {	FILE *destination, *source;
    	srcFile = getPath(srcFile,0);
    	destFile = getPath(destFile,0);
    	if(fopen(destFile,"r")!=NULL){
    		printf("%s already exists in this directory.\nOverwrite?"
    				"\n",getName(destFile));
    		if(getchar()=='n')
    			return;
    	}
    	destination = fopen(destFile, "wb");
    	source = fopen(srcFile, "rb");
    	fWrite(source,destination);
    }
    So when debugging with GDB, I step past srcFile = getPath(srcFile,0); and read the value of srcFile to be "/cygdrive/c/Users/.../foo.txt" as expected, but when I step past the next line (destFile = ...), the value of srcFile changes to "/cygdrive/c/Users/.../foS". I've tried allocating memory for the strings, but problem persists.

    Can anyone see why this is happening?
    Attached Files Attached Files
    • File Type: c hw6.c (2.7 KB, 209 views)
    Last edited by LanguidLegend; 11-10-2011 at 08:44 AM.

  2. #2
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    In general, you're not checking anywhere that your strings are long enough to deal with the data you're putting in them.

    Next step, turn up compiler warnings and see what you get :
    $ g++ -Wall -Wextra -c hw6.c
    hw6.c: In function `int isDir(char*)':
    hw6.c:15:6: warning: unused variable `success'
    hw6.c: In function `char** breakdown(char*)':
    hw6.c:47:18: warning: address of local variable `dirList' returned
    hw6.c: In function `char* getPath(char*, int)':
    hw6.c:74:9: warning: deprecated conversion from string constant to `char*'
    hw6.c: In function `void move(char**)':
    hw6.c:103:28: error: cannot convert `char**' to `const char*' for argument `1' to `size_t strlen(const char*)'
    hw6.c:100:8: warning: unused variable `ch'
    hw6.c: In function `int main(int, char**)':
    hw6.c:117:38: warning: deprecated conversion from string constant to `char*'
    hw6.c:117:38: warning: deprecated conversion from string constant to `char*'

    Any of these could be the problem.

    The error on line 47 is a problem - local variables get destroyed once you return from a function so accessing them after returning gives you random garbage at best. Pass in dirlist as a parameter and fill it in instead.

    The "deprecated conversion from sting const to char *" means you're passing a string constant (e.g. "foo.txt") as a char *. That's OK if you only read it, but if you try and write to a string constant anything can happen (it's called a constant for a reason). Make the parameter type const char * since that's what string constants are - and then work through the errors from this change to see where you're trying to modify those read-only strings. Note in particular that strtok modifies the input string so you'll have problems there, but you're also using strcat and strcpy on them.

    Code:
            char* sFile = (char *)malloc(80 * sizeof(char));
            char* dFile = (char *)malloc(80 * sizeof(char));
            dFile = getPath(destFile,0);
            sFile = getPath(srcFile,0);
    This makes no sense - you're allocating space and then throwing it away by having sFile and dFile point to something else entirely. And as a note, sizeof(char) is defined to always be 1 so no need for it here in the malloc calls. And don't cast the return value of malloc for C code - it doesn't ever help and can hide errors.

    You'll need to allocate space for buf before passing it to getcwd().

    You need to allocate strlen(x)+1 if you want a copy of a string to account for the trailing NUL. Look into using the non-standard but often available strdup to make life easier.

    path="" doesn't do what you think it does. Try strcpy(path, "") - but then again this will fail since you're passing const strings into copy() so you'll have to rethink what you're doing in that part of the code.

    fWrite would be better done using fread() and fwrite(). And don't use feof() to control the loop, use check the return value of the read function for EOF instead.

    That'll get you started. I'm sure more will pop up once you fix these problems.

  3. #3
    Registered User
    Join Date
    May 2010
    Location
    San Jose, California, United States
    Posts
    22
    Thanks for the quick response! *thumbs up*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Overwriting an integer array
    By bridle17 in forum C Programming
    Replies: 2
    Last Post: 10-02-2011, 11:25 PM
  2. How can I avoid overwriting into an array?
    By Pztar in forum C Programming
    Replies: 3
    Last Post: 06-07-2011, 03:17 PM
  3. Seemingly simple array program yielding bizarre output
    By alter.ego in forum C Programming
    Replies: 7
    Last Post: 04-07-2011, 11:15 AM
  4. Overwriting all in array, why?
    By guesst in forum C Programming
    Replies: 7
    Last Post: 10-09-2008, 05:56 PM
  5. Overwriting Array with New Array
    By Osiris990 in forum C++ Programming
    Replies: 14
    Last Post: 02-25-2008, 01:56 PM

Tags for this Thread