LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-06-2020, 01:42 PM   #1
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311
Blog Entries: 2

Rep: Reputation: 16
Question compiler claims memory that was already malloc-ed was not malloc-ed


I malloc-ed a string "string", and then I freed it, but I get this strange error message:
Code:
==8335==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x7fffffffe41e in thread T0
    #0 0x4b7db0  (/media/a/LG/AC/Learn/Programming/C/arrays/a.out+0x4b7db0)
    #1 0x4e97c4  (/media/a/LG/AC/Learn/Programming/C/arrays/a.out+0x4e97c4)
    #2 0x7ffff6ee582f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #3 0x417e08  (/media/a/LG/AC/Learn/Programming/C/arrays/a.out+0x417e08)

AddressSanitizer can not describe address in more detail (wild memory access suspected).
SUMMARY: AddressSanitizer: bad-free (/media/a/LG/AC/Learn/Programming/C/arrays/a.out+0x4b7db0) 
==8335==ABORTING
[Inferior 1 (process 8335) exited with code 01]
(gdb)
My code is below:
string_simple.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "printStr.h"
#include "strIsEmpty.h"


int main(int argc, char ** argv)
{
	//Verify User input non-empty string
		if(strIsEmpty(argv[1]))
		{
			printf("String NOT detected..\n  Please rerun program and enter a string\n");
			exit(EXIT_FAILURE);
		}
		
	int length = strlen(argv[1]);

	//Allocate memory for array in heap
		char* string = (char*)malloc((length + 1) * sizeof(char));
		string = argv[1];

	//Padding
		string[length] = '\0';

	//Print out char array
		printStr(string);

	//Free
		free(string);
}

printStr.h
Code:
	void printStr(char* letter)     
	{
		printf("%s\n", letter);
		printf("\n");
	}

strIsEmpty.h
Code:
	short int strIsEmpty(char * str)
	{
		if(str == NULL)
		{
			return(1);
		}
		else
		{
			return(0);
		}
	}
Subject code successfully compiles with:
Code:
$ clang -g -std=c99 -Wall -Wvla -Werror -fsanitize=address,undefined ./string_simple.c
but when I actually run it with an argument:
Code:
/arrays$ ./a.out asdfuie
I get the aforesaid error.

File stats are:
Code:
.../arrays$ ls -l string_simple.c printStr.h strIsEmpty.h
-rw-rw-r-- 1 a a  77 Jun  6 02:52 printStr.h
-rw-rw-r-- 1 a a 580 Jun  6 14:17 string_simple.c
-rw-rw-r-- 1 a a  98 Jun  6 12:14 strIsEmpty.h
I tried looking on web, the only thing remotely related didn't really seem to directly have to do with my situation:
1) stackoverflow
2) github
3) hoelz.ro/blog

I run the above in gdb, but even though I step through main line by line, still nothing can be seen. The only thing that I can see is that only after the very last line of the code:
Code:
	free(string);
do I get the above error.


Why do I get this error? Aren't we supposed to free anything malloc-ed?
 
Old 06-06-2020, 01:44 PM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,872
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
Code:
    //Allocate memory for array in heap
      char* string = (char*)malloc(length + 1);
--      string = argv[1];
--      string[length] = '\0';
        strcpy (string, argv[1]);
(Note sizeof(char) is 1)

Last edited by NevemTeve; 06-06-2020 at 01:53 PM.
 
2 members found this post helpful.
Old 06-06-2020, 01:58 PM   #3
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
Quote:
Originally Posted by andrew.comly View Post
I malloc-ed a string "string", and then I freed it, but I get this strange error message:


My code is below:
string_simple.c
Code:
//snipped
		string = argv[1];
//snipped
		free(string);
}


Why do I get this error? Aren't we supposed to free anything malloc-ed?
You allocated space for the string but then pointed it at argv[1]. This is memory that is allocated elsewhere. What you want to do is copy the string that argv[1] points to and this is done with strcpy or strncpy (see your manpages for strcpy).
 
3 members found this post helpful.
Old 06-07-2020, 10:51 AM   #4
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311

Original Poster
Blog Entries: 2

Rep: Reputation: 16
Talking solution

Thinking of my past viewing of Jacob Sorber's tutorial on how strcpy can be hacked, I decided on strncpy.
After reading the below manpages for strncpy:
Code:
20        The  strncpy()  function is similar, except that at most n bytes of src
21        are copied.  Warning: If there is no null byte among the first n  bytes
22        of src, the string placed in dest will not be null-terminated.
23 
24        If  the  length of src is less than n, strncpy() writes additional null
25        bytes to dest to ensure that a total of n bytes are written.
26 
27        A simple implementation of strncpy() might be:
28 
29            char *
30            strncpy(char *dest, const char *src, size_t n)
31            {
32                size_t i;
33 
34                for (i = 0; i < n && src[i] != '\0'; i++)
35                    dest[i] = src[i];
36                for ( ; i < n; i++)
37                    dest[i] = '\0';
38 
39                return dest;
40            }
I wasn't sure about what number to choose for "n", so I had to experiment first with
Code:
                    
length = strlen(argv[1]);
...
strncpy(string,argv[1],(length));
which earned me:
Code:
                    
(gdb) p string
$1 = 0x60200000eff0 "fjdska\276"
, which is an unpadded string.

I tried again with:
Code:
strncpy(string,argv[1],(length+1));
allowing for strncpy's padding function to not get cut off, thus my final solution for this post:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "printStr.h"
#include "strIsEmpty.h"


int main(int argc, char ** argv)
{
	//Verify User input non-empty string
		if(strIsEmpty(argv[1]))
		{
			printf("String NOT detected..\n  Please rerun program and enter a string\n");
			exit(EXIT_FAILURE);
		}

	int length = strlen(argv[1]);

	//Allocate memory for array in heap
		char* string = (char*)malloc((length + 1) * sizeof(char));

	//Point 'string' variable at argv[1];
		strncpy(string,argv[1],(length+1));			//strncpy will only insert padding on end if "n" is one more than the true length of the string

	//Print out char array
		printStr(string);

	//Free
		free(string);
}

Nota Bene: It seemed strange at first how you have to feed length + 1 in the strncpy function, but since I'm already used to "length + 1" whenever mallocing strings, all I have to remember is that strncpy is parallel with malloc to ensure padding.
 
Old 06-07-2020, 10:54 AM   #5
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,964

Rep: Reputation: 7332Reputation: 7332Reputation: 7332Reputation: 7332Reputation: 7332Reputation: 7332Reputation: 7332Reputation: 7332Reputation: 7332Reputation: 7332Reputation: 7332
probably it is a bit late this time, but I would suggest you to try valgrind, that can definitely help in such cases.
 
1 members found this post helpful.
Old 06-07-2020, 12:17 PM   #6
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,872
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
In this context `strcpy` is perfectly okay, but there is dedicated function for string duplication called `strdup`:
Code:
char *string= strdup (argv[1]);
 
Old 06-08-2020, 10:10 AM   #7
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
Quote:
Originally Posted by andrew.comly View Post

Nota Bene: It seemed strange at first how you have to feed length + 1 in the strncpy function, but since I'm already used to "length + 1" whenever mallocing strings, all I have to remember is that strncpy is parallel with malloc to ensure padding.
strlen gives you the number of char in the string, up to but not including the nul byte (string terminator). When you copy a string you want the string to be terminated so you also want to copy that byte (hence +1). If you don't copy it you can assign it after copying but before you use the string.
 
  


Reply

Tags
address, free, malloc, strings



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Virtual Memory limit exhausted at 1TB? malloc/mmap failures even with free memory mfkraft Linux - Server 2 09-16-2012 08:27 AM
Memory map or physical address of some memory allocated by malloc demon007 Programming 1 02-04-2012 06:17 AM
Memory leaks.. *** glibc detected *** ./SuffixTree: malloc(): memory corruption: 0x00 evansash Programming 12 03-21-2011 01:17 PM
urpmi claims I already have bittorrent installed! pdmackenzie Linux - Software 1 10-21-2004 06:57 AM
rpm -q claims "installed" but rpm -ivh claims "already installed" topgunjones Linux - Software 3 01-29-2004 08:31 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:52 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration