473,394 Members | 1,709 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,394 software developers and data experts.

possible memory leak?

Hello, All!

I have this small piece of code, where segmentation fault happenes only upon
runnin code. No problems during debug (JFI I'm using gdb-6.3):

----
struct host_info {
char *host;
int port;
char *path;
int is_ftp;
char *user;
};

....

int parse_url(char *url, struct host_info *h)
{
char *cp, *sp, *up, *pp,*ptr;

if (strncmp(url, "ftp://", 6) == 0) {
h->port = 21;
h->host = url + 6;
h->is_ftp = 1;
} else {
return -1;
}

sp = strchr(h->host, '/');
if (sp) {
*sp++ = '\0'; /* XXX */
h->path = sp;

} else
h->path = strdup("");

up = strrchr(h->host, '@');
if (up != NULL) {
h->user = h->host;
*up++ = '\0';
h->host = up;
} else
h->user = NULL;

pp = h->host;

cp = strchr(pp, ':');
if (cp != NULL) {
*cp++ = '\0';
h->port = htons(atoi(cp));
}

return 0;
}
-----

The problem happenes at 'XXX' mark. I also examined source code with
'splint', which gave me some hints:

---
Implicitly only storage h->path (type char *) not released before assignment
(sp aliases h->host): h->path = sp A memory leak has been detected.
Only-qualified storage is not released before the last reference to it is
lost.

Implicitly only storage h->path (type char *) not released before
assignment: h->path = strdup("")
---

I'm still confused. What can be the problem?

Thank you.

With best regards, Roman Mashak. E-mail: mr*@tusur.ru
Nov 15 '05 #1
13 1940
Roman Mashak wrote:
Hello, All!

I have this small piece of code, where segmentation fault happenes only upon
runnin code. No problems during debug (JFI I'm using gdb-6.3): .... int parse_url(char *url, struct host_info *h)
{
char *cp, *sp, *up, *pp,*ptr; .... sp = strchr(h->host, '/');
if (sp) {
*sp++ = '\0'; /* XXX */
h->path = sp;
} else
h->path = strdup(""); ....

In the branch above, you assign two different things to h->path,
depending on sp. One is derived from a function argument and the other
one is an allocated memory. This is begging for problems. Depending on
your code design, a few things could happen.

First, since I could not see you freeing the memory allocated by
strdup(), you have a chance of memory leak. If you were to free the
memory, then you face the danger of freeing something you had not
allocated if sp is assigned to h->path. The three possible solutions are
to always allocate, never allocate or remember whether you have
allocated or not.

Also, depending on how you call the function, your line marked with XXX
may cause a problem if your url (the first function argument) is a
string literal. Your XXX line modifies it, which is a clear example of
undefined behaviour.

You might try changing the offending bit to something like:

h->path = strdup(h->host);
/* Remember to check that strdup() succeeded! */
sp = strchr(h->path, '/');
if (sp) {
*sp = '\0'; /* XXX */
} else
*h->path = '\0';

(keeping in mind that strdup() is non-standard and hence out of the
scope of this newsgroup). Repeat the same for h->user and h->port.
Remember to free the memory afterwards.

Alternatively, redesign your code so that it does not need copying the
strings all the time. (Possibly by making only one copy and working on
it instead of the function argument.)
The problem happenes at 'XXX' mark. I also examined source code with
'splint', which gave me some hints:

---
Implicitly only storage h->path (type char *) not released before assignment
(sp aliases h->host): h->path = sp A memory leak has been detected.
Only-qualified storage is not released before the last reference to it is
lost.

Implicitly only storage h->path (type char *) not released before
assignment: h->path = strdup("")
---

I'm still confused. What can be the problem?


I hope I have managed to clear at least some of the confusion.

Peter

Nov 15 '05 #2
I have never seen you applied memory units for your struct " *h " ,
and you assign a constant to an variable which has no room. there will
be a segment fault.

Nov 15 '05 #3

ke******@hotmail.com wrote:
I have never seen you applied memory units for your struct " *h " ,
and you assign a constant to an variable which has no room. there will
be a segment fault.


The way the argument "h" is passed to function parse_url(), indicates
that the caller of this function should have already allocated
memory for "struct host_info *h". Note that the type of "h" is
"struct host_info *" and not "struct host_info **".

Even if you allocate the memory in function parse_url(), its of no
use because its no longer accessible after you return.

Nov 15 '05 #4
Thanks to all for replies.

Unfortunately, I still have the problem.
[OT]
The curious thing is this code is taken from 'busybox' package (sure it's OT
here) where it works fine (and I didn't change anything). I also explored
'busybox' code and didn't find any allocation of memory, even I traced with
debugger and it all works fine there.
[/OT]

What's wrong with the code like this (code in original post gets dumped at
*sp++ = '\0' statement, so I decided to simplify a little):

char *s = "abcde"; /* s point to 'a' character */
*s = 'A'; /* replace 'a' with 'A' */
s++; /* move pointer to 'b' */

With best regards, Roman Mashak. E-mail: mr*@tusur.ru
Nov 15 '05 #5

Roman Mashak wrote:
Thanks to all for replies.

Unfortunately, I still have the problem.
[OT]
The curious thing is this code is taken from 'busybox' package (sure it's OT
here) where it works fine (and I didn't change anything). I also explored
'busybox' code and didn't find any allocation of memory, even I traced with
debugger and it all works fine there.
[/OT]

What's wrong with the code like this (code in original post gets dumped at
*sp++ = '\0' statement, so I decided to simplify a little):

char *s = "abcde"; /* s point to 'a' character */
*s = 'A'; /* replace 'a' with 'A' */
s++; /* move pointer to 'b' */

With best regards, Roman Mashak. E-mail: mr*@tusur.ru

Does
http://www.eskimo.com/~scs/C-faq/q16.6.html
help?

Nov 15 '05 #6

Roman Mashak wrote:
Thanks to all for replies.
What's wrong with the code like this (code in original post gets dumped at
*sp++ = '\0' statement, so I decided to simplify a little):

char *s = "abcde"; /* s point to 'a' character */
*s = 'A'; /* replace 'a' with 'A' */
s++; /* move pointer to 'b' */


http://www.eskimo.com/~scs/C-faq/q1.32.html

You shouldn't modify string literals, such as
"abcde". Make a copy first, or do something like this:

char s[] = "abcde";

-David

Nov 15 '05 #7
Roman Mashak wrote:
What's wrong with the code like this (code in original post gets dumped at
*sp++ = '\0' statement, so I decided to simplify a little):

char *s = "abcde"; /* s point to 'a' character */
*s = 'A'; /* replace 'a' with 'A' */
s++; /* move pointer to 'b' */

With best regards, Roman Mashak. E-mail: mr*@tusur.ru


The problem here is trying to change the contents of a string literal.
For historical reasons, a type of "abcde" is char*, but it should be
treated as const char*. Changing the contents may "work" in some
implementations, but it is undefined. Imagine for example that all
string literals are stored in read-only memory. Trying to change them
may result in ignoring the change or in a run-time error on fussier systems.

Peter

Nov 15 '05 #8
Hello, Peter!
You wrote on Thu, 11 Aug 2005 21:53:38 +0100:

??>> What's wrong with the code like this (code in original post gets
??>> dumped at *sp++ = '\0' statement, so I decided to simplify a little):
??>> char *s = "abcde"; /* s point to 'a' character */
??>> *s = 'A'; /* replace 'a' with 'A' */
??>> s++; /* move pointer to 'b' */
??>>
??>> With best regards, Roman Mashak. E-mail: mr*@tusur.ru

PP> The problem here is trying to change the contents of a string literal.
PP> For historical reasons, a type of "abcde" is char*, but it should be
PP> treated as const char*. Changing the contents may "work" in some
PP> implementations, but it is undefined. Imagine for example that all
PP> string literals are stored in read-only memory. Trying to change them
PP> may result in ignoring the change or in a run-time error on fussier
PP> systems.
Why is it not assumed that array (char s[] = "abcd") can be also allocated
in ROM? My compiler has option allowing to treat string literals as writable
(but it's not safe).

Let's consider my original peice of code (here I put full version that
crashes):
-----
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>

struct host_info {
char *host;
int port;
char *path;
int is_ftp;
char *user;
};

int parse_url(char *url, struct host_info *h)
{
char *cp, *sp, *up, *pp;
char *host, *path;

if (strncmp(url, "ftp://", 6) == 0) {
host = url + 6;
h->port = 21;
h->host = url + 6;
h->is_ftp = 1;
} else {
return -1;
}

sp = strchr(h->host, '/');
if (sp) {
*sp++ = '\0'; /* XXX */
h->path = sp;
} else
h->path = strdup("");

up = strrchr(host, '@');
if (up != NULL) {
h->user = h->host;
*up++ = '\0';
h->host = up;
} else
h->user = NULL;

pp = h->host;

cp = strchr(pp, ':');
if (cp != NULL) {
*cp++ = '\0';
h->port = htons(atoi(cp));
}

return 0;
}

int main(void)
{
struct host_info *hh;
hh = (struct host_info*)malloc(sizeof(struct host_info));

int rc = parse_url("ftp://192.168.11.197/pub/test.txt", 0);
printf("return status rc=%d\n", rc);

return 0;
}
-----

As I stated earlier, segfault happens at XXX mark. If I'm right, then
compiler treats that line as follows:
1) evaluate *sp
2) put '\0' into memory area pointed by 'sp'
3) increment pointer value

So, I suspect crash occurs at second step.
[OT]
By the way, no faults happen while debug in GDB. Basically debuggers are
supposed to reveal such kinds of problems.
[/OT]

With best regards, Roman Mashak. E-mail: mr*@tusur.ru
Nov 15 '05 #9
On Fri, 12 Aug 2005 11:12:49 +0900, "Roman Mashak" <mr*@tusur.ru>
wrote in comp.lang.c:
Hello, Peter!
You wrote on Thu, 11 Aug 2005 21:53:38 +0100:

??>> What's wrong with the code like this (code in original post gets
??>> dumped at *sp++ = '\0' statement, so I decided to simplify a little):
??>> char *s = "abcde"; /* s point to 'a' character */
??>> *s = 'A'; /* replace 'a' with 'A' */
??>> s++; /* move pointer to 'b' */
??>>
??>> With best regards, Roman Mashak. E-mail: mr*@tusur.ru

PP> The problem here is trying to change the contents of a string literal.
PP> For historical reasons, a type of "abcde" is char*, but it should be
PP> treated as const char*. Changing the contents may "work" in some
PP> implementations, but it is undefined. Imagine for example that all
PP> string literals are stored in read-only memory. Trying to change them
PP> may result in ignoring the change or in a run-time error on fussier
PP> systems.
Why is it not assumed that array (char s[] = "abcd") can be also allocated
in ROM? My compiler has option allowing to treat string literals as writable
(but it's not safe).

Let's consider my original peice of code (here I put full version that
crashes):
-----
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>

struct host_info {
char *host;
int port;
char *path;
int is_ftp;
char *user;
};

int parse_url(char *url, struct host_info *h)
{
char *cp, *sp, *up, *pp;
char *host, *path;

if (strncmp(url, "ftp://", 6) == 0) {
host = url + 6;
h->port = 21;
h->host = url + 6;
h->is_ftp = 1;
} else {
return -1;
}

sp = strchr(h->host, '/');
if (sp) {
*sp++ = '\0'; /* XXX */
h->path = sp;
} else
h->path = strdup("");

up = strrchr(host, '@');
if (up != NULL) {
h->user = h->host;
*up++ = '\0';
h->host = up;
} else
h->user = NULL;

pp = h->host;

cp = strchr(pp, ':');
if (cp != NULL) {
*cp++ = '\0';
h->port = htons(atoi(cp));
}

return 0;
}

int main(void)
{
struct host_info *hh;
hh = (struct host_info*)malloc(sizeof(struct host_info));

int rc = parse_url("ftp://192.168.11.197/pub/test.txt", 0);
This is EXACTLY what three people just told you, and even posted links
to the specific FAQ page. You are passing a string literal to a
function that tries to modify it. Modifying a string literal is
undefined behavior. One possibility of undefined behavior is a
program "crash".
printf("return status rc=%d\n", rc);

return 0;
}
-----

As I stated earlier, segfault happens at XXX mark. If I'm right, then
compiler treats that line as follows:
1) evaluate *sp
2) put '\0' into memory area pointed by 'sp'
3) increment pointer value

So, I suspect crash occurs at second step.
[OT]
By the way, no faults happen while debug in GDB. Basically debuggers are
supposed to reveal such kinds of problems.
[/OT]

With best regards, Roman Mashak. E-mail: mr*@tusur.ru


At the top of main(), add this definition:

char url_to_parse [] = "ftp://192.168.11.197/pub/test.txt";

....then change the function call to:

int rc = parse_url(url_to_parse, 0);

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 15 '05 #10
"Roman Mashak" <mr*@tusur.ru> writes:
[...]
Why is it not assumed that array (char s[] = "abcd") can be also allocated
in ROM? My compiler has option allowing to treat string literals as writable
(but it's not safe).


Because char s[] = "abcd" creates an array of 5 characters with the
initial value {'a', 'b', 'c', 'd', '\0'}. The array is not const, and
it's not a string literal; it's perfectly legal to modify it. (A
string literal in an initializer doesn't create the same kind of
not-const-but-don't-touch-it array that a string literal in most other
contexts create.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #11
Hello, Jack!
You wrote on Thu, 11 Aug 2005 21:30:05 -0500:

JK> This is EXACTLY what three people just told you, and even posted links
JK> to the specific FAQ page. You are passing a string literal to a
JK> function that tries to modify it. Modifying a string literal is
JK> undefined behavior. One possibility of undefined behavior is a
JK> program "crash".
I've read the links carefully but didn't confronted with my code properly.
My mistake, thanks a lot!
So, as I understand, the most safe practice is to avoid string literals? (as
well as 'strcpy' as claimed in another thread)

With best regards, Roman Mashak. E-mail: mr*@tusur.ru
Nov 15 '05 #12
Roman Mashak wrote:
So, as I understand, the most safe practice is to avoid string literals? (as
well as 'strcpy' as claimed in another thread)


Avoid *modifying* string literals. String literals as such are difficult
to avoid, just like numeric literals. There's nothing wrong with
strcpy(), provided you know how to use it.

Peter

Nov 15 '05 #13
Peter Pichler wrote:
Roman Mashak wrote:
So, as I understand, the most safe practice is to avoid string
literals? (as well as 'strcpy' as claimed in another thread)


Avoid *modifying* string literals. String literals as such are
difficult to avoid, just like numeric literals. There's nothing
wrong with strcpy(), provided you know how to use it.


If you are using gcc, use the -Wwrite-strings option. This will
effectively declare all those strings as const, and you will get a
compile time error if you try to write to them.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 15 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: ranjeet.gupta | last post by:
Dear All Is the Root Cause of the Memory corruption is the Memory leak, ?? suppose If in the code there is Memory leak, Do this may lead to the Memory Corruption while executing the program ? ...
17
by: José Joye | last post by:
Hi, I have implemented a Service that is responsible for getting messages from a MS MQ located on a remote machine. I'm getting memory leak from time to time (???). In some situation, it is...
4
by: Don Nell | last post by:
Hello Why is there a memory leak when this code is executed. for(;;) { ManagementScope scope = new ManagementScope(); scope.Options.Username="username"; scope.Options.Password="password";...
20
by: jeevankodali | last post by:
Hi I have an .Net application which processes thousands of Xml nodes each day and for each node I am using around 30-40 Regex matches to see if they satisfy some conditions are not. These Regex...
3
by: Emmanuel Gehin | last post by:
When I use the following code in VB.NET : Public Function test() As String Try Dim da1 As OdbcDataAdapter Dim i As Int32 Dim tfem As DataTable For i = 0 To 1000 da1 = New...
3
by: Jim Land | last post by:
Jack Slocum claims here http://www.jackslocum.com/yui/2006/10/02/3-easy-steps-to-avoid-javascript- memory-leaks/ that "almost every site you visit that uses JavaScript is leaking memory". ...
1
by: Joe Peterson | last post by:
I've been doing a lot of searching on the topic of one of Python's more disturbing issues (at least to me): the fact that if a __del__ finalizer is defined and a cyclic (circular) reference is...
7
by: Ragnar Agustsson | last post by:
Hi all I have been wandering about the best way to sandbox memory leaks in 3rd party libraries when using them from the .Net framework. I have a 3rd party library, written in C++, that leaks a...
22
by: Peter | last post by:
I am using VS2008. I have a Windows Service application which creates Crystal Reports. This is a multi theaded application which can run several reports at one time. My problem - there is a...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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
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...

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.