473,662 Members | 2,596 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Struggling with libraries

I'm just learning C as another language, and I'm trying to build some
utilities into a library. I have this (crude I know) function:

void insert(char* insrt, char* source, int place){
char temp[strlen(insrt)+s trlen(source)+1]; strncpy(temp, source, place);
temp[place]='\0';
strcat(temp, insrt);
strcat(temp, source+place);
strcpy(source, temp);
}

In a simple file, it all works, but in a static library, when I call it I
get a segnmentation fault. The villain is the final strcpy.

I tried returning temp instead and that doesn't work either, I don't get
quite the string that exists in the function (and the compiler warns about
returning a local variable).

I know there's a solution, I just have no idea what it is. Any help would
be great.

Tony
Apr 17 '06 #1
18 1894
Tony Burrows wrote:
I'm just learning C as another language, and I'm trying to build some
utilities into a library. I have this (crude I know) function:

void insert(char* insrt, char* source, int place){
char temp[strlen(insrt)+s trlen(source)+1]; strncpy(temp, source, place);
temp[place]='\0';
strcat(temp, insrt);
strcat(temp, source+place);
strcpy(source, temp);
}

In a simple file, it all works, but in a static library, when I call it I
get a segnmentation fault. The villain is the final strcpy.

I tried returning temp instead and that doesn't work either, I don't get quite the string that exists in the function (and the compiler warns about
returning a local variable). It's illegal to return pointers to auto objects.

I know there's a solution, I just have no idea what it is. Any help would
be great.


WIthout seeing how it is beeing called, hard to tell.

Be very very sure your 'source' has enough room for
'insrt'.
Apr 17 '06 #2
Tony Burrows wrote:
I'm just learning C as another language, and I'm trying to build some
utilities into a library. I have this (crude I know) function:

void insert(char* insrt, char* source, int place){
char temp[strlen(insrt)+s trlen(source)+1]; strncpy(temp, source,
place); temp[place]='\0';
strcat(temp, insrt);
strcat(temp, source+place);
strcpy(source, temp);
}

In a simple file, it all works, but in a static library, when I call
it I get a segnmentation fault. The villain is the final strcpy.

I tried returning temp instead and that doesn't work either, I don't
get quite the string that exists in the function (and the compiler
warns about returning a local variable).

I know there's a solution, I just have no idea what it is. Any help
would be great.


You need to help us. Post a COMPLETE minimal program that demonstrates
the problem. I all likelihood, there is not sufficient room in source
to contain the expanded string, but how can we tell?


Brian
Apr 17 '06 #3
On Mon, 17 Apr 2006 18:46:44 +0200, Nils O. Selåsdal wrote:
Tony Burrows wrote:
I'm just learning C as another language, and I'm trying to build some
utilities into a library. I have this (crude I know) function:

void insert(char* insrt, char* source, int place){
char temp[strlen(insrt)+s trlen(source)+1]; strncpy(temp, source, place);
temp[place]='\0';
strcat(temp, insrt);
strcat(temp, source+place);
strcpy(source, temp);
}

In a simple file, it all works, but in a static library, when I call it I
get a segnmentation fault. The villain is the final strcpy.

I tried returning temp instead and that doesn't work either, I don't get

quite the string that exists in the function (and the compiler warns about
returning a local variable).

It's illegal to return pointers to auto objects.

I know there's a solution, I just have no idea what it is. Any help would
be great.


WIthout seeing how it is beeing called, hard to tell.

Be very very sure your 'source' has enough room for
'insrt'.

I've called it from a simple little program:

#include <stdio.h>
#include "insert.h"

int main(void){
char *str1 = "You are a nutcase!";
char *str2 = "big ";
puts(str1);
puts(str2);
insert(str2, str1, 10);
return 0;
}

insert.h is
#include <string.h>
void insert(char* insrt, char* source, int place);
void insertn(char* insrt, char* source, int place, int size);

Compiled with gcc -o testInsert testInsert.c insert.c

If I put print statements in, then the segmentation fault happens in the
insert function when strcpy(source, temp) is executed.

If I created a string on the heap with (I think) malloc and returned a
pointer to that, would that deal with the problem? If so, is it the right
way? The C programming books don't seem to touch on this.

Tony

Apr 17 '06 #4

"Tony Burrows" <to**@tonyburro ws.com> wrote in message
news:pa******** *************** *****@tonyburro ws.com...
I'm just learning C as another language, and I'm trying to build some
utilities into a library. I have this (crude I know) function:

void insert(char* insrt, char* source, int place){
char temp[strlen(insrt)+s trlen(source)+1]; strncpy(temp, source, place);
temp[place]='\0';
strcat(temp, insrt);
strcat(temp, source+place);
strcpy(source, temp); Crash! source is not large enough to hold the new characters.
You need to allocate or reallocate space. What you need is:

char * insert(char* insrt, char* source, int place){
char *temp=NULL;
size_t nch = strlen(insrt)+s trlen(source)+1 ;
temp = malloc(nch);
if ( temp ) {
strncpy(temp, source, place);
temp[place]='\0';
strcat(temp, insrt);
strcat(temp, source+place);
}
return temp;
}

Or you could reallocate source

void insert(char* insrt, char** source, int place){
char *temp=NULL;
size_t nch = strlen(insrt)+s trlen(source)+1 ;
temp = realloc(*source , nch);
if ( temp ) {
strncpy(temp, source, place);
temp[place]='\0';
strcat(temp, insrt);
strcat(temp, source+place);
}
else {
/* Decide what to do if the realloc fails */
...
}
}

In a simple file, it all works, but in a static library, when I call it I
get a segnmentation fault. The villain is the final strcpy.

I tried returning temp instead and that doesn't work either, I don't get
quite the string that exists in the function (and the compiler warns about
returning a local variable).

I know there's a solution, I just have no idea what it is. Any help would
be great.

Tony

--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project
Apr 17 '06 #5
Tony Burrows wrote:
I've called it from a simple little program:

#include <stdio.h>
#include "insert.h"

int main(void){
char *str1 = "You are a nutcase!";
char *str2 = "big ";
puts(str1);
puts(str2);
insert(str2, str1, 10);
return 0;
}

insert.h is
#include <string.h>
void insert(char* insrt, char* source, int place);
void insertn(char* insrt, char* source, int place, int size);

Compiled with gcc -o testInsert testInsert.c insert.c

If I put print statements in, then the segmentation fault happens in
the insert function when strcpy(source, temp) is executed.
You have two problems. One is that string literals are not modifiable.
Passing str1 to a function that modifies it is undefined behavior. For
you, luckily, that UB was a crash and alerted you to the problem.

The second problem is that even if it was modifiable, str1 is an array
of 18 characters, with no place to put in any extras.
If I created a string on the heap with (I think) malloc and returned a
pointer to that, would that deal with the problem? If so, is it the
right way? The C programming books don't seem to touch on this.


Inside the insert() function? That's one way to do it. Some people
don't like to have functions that allocate memory and leave the
responsibility to deallocate to the caller. The other way is to pass in
a buffer large enough to hold the resulting string.

void insert(const char* insrt, const char* source, char *dest, int
place);

Allocate dest in the calling function, with its size equal to the
string length of insrt + source + 1.

Brian
Apr 17 '06 #6
Tony Burrows <to**@tonyburro ws.com> writes:
On Mon, 17 Apr 2006 18:46:44 +0200, Nils O. Selåsdal wrote:
Tony Burrows wrote:
I'm just learning C as another language, and I'm trying to build some
utilities into a library. I have this (crude I know) function:

void insert(char* insrt, char* source, int place){
char temp[strlen(insrt)+s trlen(source)+1]; strncpy(temp, source, place);
temp[place]='\0';
strcat(temp, insrt);
strcat(temp, source+place);
strcpy(source, temp);
}
[snip] I've called it from a simple little program:

#include <stdio.h>
#include "insert.h"

int main(void){
char *str1 = "You are a nutcase!";
char *str2 = "big ";
puts(str1);
puts(str2);
insert(str2, str1, 10);
return 0;
}

insert.h is
#include <string.h>
void insert(char* insrt, char* source, int place);
void insertn(char* insrt, char* source, int place, int size);


Two problems. First, you're attempting to modify a string literal.
Second, even if the string literal were modifiable (as it might be on
some implementations ), you haven't allocated enough space to hold the
result.

--
Keith Thompson (The_Other_Keit h) 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.
Apr 17 '06 #7


Default User wrote On 04/17/06 15:08,:
Tony Burrows wrote:

I've called it from a simple little program:

#include <stdio.h>
#include "insert.h"

int main(void){
char *str1 = "You are a nutcase!";
char *str2 = "big ";
puts(str1);
puts(str2);
insert(str2, str1, 10);
return 0;
}

insert.h is
#include <string.h>
void insert(char* insrt, char* source, int place);
void insertn(char* insrt, char* source, int place, int size);

Compiled with gcc -o testInsert testInsert.c insert.c

If I put print statements in, then the segmentation fault happens in
the insert function when strcpy(source, temp) is executed.

You have two problems. One is that string literals are not modifiable.
Passing str1 to a function that modifies it is undefined behavior. For
you, luckily, that UB was a crash and alerted you to the problem.

The second problem is that even if it was modifiable, str1 is an array
of 18 characters, with no place to put in any extras.


ITYM "19 characters;" C's most characteristic error strikes
again. Also, since the O.P. is a beginner it's as well to avoid
using shorthand language that is literally untrue: str1 is not an
array, but a pointer. (And it's not a "pointer to an array,"
either.) A review of Section 6 in the FAQ <http://www.c-faq.com/>
is recommended.

--
Er*********@sun .com

Apr 17 '06 #8
Fred Kleinschmidt wrote:
"Tony Burrows" <to**@tonyburro ws.com> wrote in message
news:pa******** *************** *****@tonyburro ws.com...
I'm just learning C as another language, and I'm trying to build some
utilities into a library. I have this (crude I know) function:

void insert(char* insrt, char* source, int place){
char temp[strlen(insrt)+s trlen(source)+1]; strncpy(temp, source, place);
temp[place]='\0';
strcat(temp, insrt);
strcat(temp, source+place);
strcpy(source, temp); Crash! source is not large enough to hold the new characters.


Without the call you don't know that this is the only problem, and in
fact given the additional information the OP has now provided it was not
the only problem.
You need to allocate or reallocate space. What you need is:

char * insert(char* insrt, char* source, int place){
char *temp=NULL;
That initialisation is pointless. In fact, if you move the definition to
after nch you can...
size_t nch = strlen(insrt)+s trlen(source)+1 ;
temp = malloc(nch);
replace the above with
char *temp = malloc(nch);
if ( temp ) {
strncpy(temp, source, place);
temp[place]='\0';
strcat(temp, insrt);
strcat(temp, source+place);
}
return temp;
}
In general, it is the sort of thing I was thinking of. Mind you, I would
not use strcat. You know where you need to copy to (with an additional
variable) so you can use strcpy and save having to scan a potentially
long string. Also I would use memcpy rather than strncpy since you know
you are not copying the entire string. Also one needs to either add
error checking or document it's lack, since if place is beyond the end
of source you have a problem.
Or you could reallocate source

void insert(char* insrt, char** source, int place){
char *temp=NULL;
size_t nch = strlen(insrt)+s trlen(source)+1 ;
temp = realloc(*source , nch);
if ( temp ) {
strncpy(temp, source, place);
temp[place]='\0';
strcat(temp, insrt);
strcat(temp, source+place);
}
else {
/* Decide what to do if the realloc fails */
...
}
}


With the additional information now provided this would not work. We now
know that source is a pointer to a string literal (which you didn't
know when writing this) and so this would still be wrong.

This shows why the OP should have provided the complete program in the
first place.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Apr 17 '06 #9
Tony Burrows wrote:
On Mon, 17 Apr 2006 18:46:44 +0200, Nils O. Selåsdal wrote:
Tony Burrows wrote:
I'm just learning C as another language, and I'm trying to build some
utilities into a library. I have this (crude I know) function:

void insert(char* insrt, char* source, int place){
char temp[strlen(insrt)+s trlen(source)+1]; strncpy(temp, source, place);
temp[place]='\0';
strcat(temp, insrt);
strcat(temp, source+place);
strcpy(source, temp);
}

In a simple file, it all works, but in a static library, when I call it I
get a segnmentation fault. The villain is the final strcpy.

I tried returning temp instead and that doesn't work either, I don't get
quite the string that exists in the function (and the compiler warns about
returning a local variable).

It's illegal to return pointers to auto objects.

I know there's a solution, I just have no idea what it is. Any help would
be great.

WIthout seeing how it is beeing called, hard to tell.

Be very very sure your 'source' has enough room for
'insrt'.

I've called it from a simple little program:

#include <stdio.h>
#include "insert.h"

int main(void){
char *str1 = "You are a nutcase!";
char *str2 = "big ";
puts(str1);
puts(str2);
insert(str2, str1, 10);
return 0;
}

insert.h is
#include <string.h>
void insert(char* insrt, char* source, int place);
void insertn(char* insrt, char* source, int place, int size);

Compiled with gcc -o testInsert testInsert.c insert.c

If I put print statements in, then the segmentation fault happens in the
insert function when strcpy(source, temp) is executed.

If I created a string on the heap with (I think) malloc and returned a
pointer to that, would that deal with the problem? If so, is it the right
way? The C programming books don't seem to touch on this.


I'm sure they do. The comp.lang.c FAQ certainly does with a much simpler
example here http://c-faq.com/strangeprob/strlitnomod.html which tells
you that string literals are not modifiable.

In addition, even if string literals were modifiable, you are trying to
make the string longer, so this would not work either:
#include <stdio.h>
#include "insert.h"

int main(void){
char str1[] = "You are a nutcase!";
char *str2 = "big ";
puts(str1);
puts(str2);
insert(str2, str1, 10);
return 0;
}

Since it would go off the end of str1.

If I was writing a function like your insert I would probably make is
malloc enough space for a new string and return the resultant string in
that rather than modifying one of the input strings.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Apr 17 '06 #10

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

Similar topics

5
1692
by: Cecil Westerhoff | last post by:
I just started with programming under linux with c++. I have programmed for years with Borland C++ Builder. So I have some experience. But I can not find the libraries for intenet stuff. (Ping, fetching a page, etc.) The only thing I found was a library for CGI. Can someone tell me where to find those libraries? Or for that mather where to look for libraries in general?
0
1546
by: Nikki Locke | last post by:
Archive-name: C++-faq/libraries/part1 Comp-lang-c++-archive-name: C++-faq/libraries/part1 Available C++ Libraries FAQ =========================== Introduction ~~~~~~~~~~~~ Dos and don'ts - (Mostly don'ts)
3
3452
by: fabio de francesco | last post by:
Hello, I have a couple of years of experience with C++. I started studying C++ syntax, then I read the B.Stroustrup's book, and eventually I went through the N.Josuttis' book on how to program with the C++ Standard Library. I am not a professional programmer however I would like to gain more knowledge of the language to get what could be considered the skills you'd expect from a professional developer ( I also know Unix
7
2610
by: Thiru | last post by:
I am writing an application that interacts with Oracle and Teradata. In order to create the executable, I need to link various Oracle and Teradata libraries. I found out that when I link the Oracle and Teradata libraries together, the Teradata API functions are not working properly. My assumption is that these libraries are sharing identical function names and parameter lists and hence the conflicts are causing the problem. Is my...
3
2317
by: joseluismarchetti | last post by:
Hello everybody, Although I am sure this is an important question for this group, I am not sure this question belongs to this group and I will be happy to move it to the correct one after you point it to me. Direct question: How can I know if a function is defined in more than one static library that I am using to link ?
23
2009
by: Matt Silberstein | last post by:
Are there any good qualities libraries out there, free or for "reasonable" cost? -- Matt Silberstein Do something today about the Darfur Genocide http://www.beawitness.org
160
4660
by: RG | last post by:
Greetings friends, This semester I have started a course in C programming. I was moving along fine until I reached to the topic of loops (feeling embarrassed among you elite programmers). My prof. would post program questions and the solutions online. For practice I would try to do the problems. I would reach to a certain point in the code, for example as far as error trapping, but when the loop arrives, like knowing whether to use...
85
5315
by: g | last post by:
Hello, is there any library for C as Boost is for C++? thanks in advance,
11
22798
by: briankind | last post by:
Hello i have these radio buttons and i wish to have the corresponding textboxes to be visible when the radiobutton is selected. any Help? snippets. thanks thanks in adv Bry
9
2525
by: DL | last post by:
That is, for an iframe with onload attribute to preset a width and height then depending on the length of its content to auto-expand instead of scrolling. The following URL is quite interesting, http://www.phpmix.org/iframe_height_auto_resize, however, it failed to work for me, OS = XP w/ sp2; brower = IE7, but my app is quite complicated... it load the iframe inside a javascrip- driven window... And their forum has been closed, so, I...
0
8435
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8345
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8857
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8633
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6186
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5655
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4348
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2763
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1754
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.