Problems with strcpy?

2 views
Skip to first unread message

Allan Bruce

unread,
Jan 19, 2003, 6:27:24 PM1/19/03
to
Hi there, can anybody please tell me why I get an error with the following?
Thanks
Allan

#include<stdio.h>
#include<time.h> /*required for time functions */
#include<stdlib.h>
#include<math.h> /*required for maths functions */

struct neural_net_structure{
int total_layers; /* total layers specified by user */
int total_neurons; /* total number of neurons in net */
int total_weights; /* total number of weights in snet */
int training_data_sets; /* number of training data sets available */
int max_epochs; /* maximum epochs to continue learning */
int seed; /* Seed for random number generation */
double lr; /* Learning rate for algorithms */
double threshold_mse; /* minimum mse before considered converged */
char *training_data_file; /* File holding all training data */
int *neurons_in_layer; /* array of neurons per layer */
double *error; /* array of average error for batch learning */
double *bias; /* Bias information for layers 1 -> output */
double *input_pattern; /* input pattern to present */
double *target_pattern; /* target pattern to present */
double **input_data; /* array of input patterns to input neurons */
double **target_data; /* array of target patterns from output neurons */
double **delta; /* delta for a specific neuron */
double **neuron; /* which neuron we are using */
double **output_from_neuron;/* ouput from specific neuron */
double ****weight; /* which weight we are using
[layer][neuron][weight][individual] - for GA */
};
typedef struct neural_net_structure nn; /* Now use nn to create a new neural
network */

#define SPREAD 1 /* This is the spread for the sigmoid function */
#define PI
(double)3.141592653589793238462643383279502884197169399675105820975
#define BIAS 1 /* 0 for no bias, 1 for bias inclusion */

#define OUTPUT_NEURONS net->neurons_in_layer[net->total_layers-1] /* Number
of neurons in output layer */
#define INPUT_NEURONS net->neurons_in_layer[0] /* Number of neurons in input
layer */
#define OUTPUT_LAYER net->total_layers-1
#define INPUT_LAYER 0

enum BOOL {TRUE, FALSE};

/**************************************************
F U N C T I O N D E F I N I T I O N S
**************************************************/
void initialise_net(nn *net);
void get_user_info(nn *net);
int get_integer(int min, int max);
double get_double(double min, double max);
void construct_net(nn *net);
void read_file(char file[], nn *net);
void csv_decode(char *string, nn *net);
void get_inputs(char *string, nn *net);
void get_outputs(char *string, nn *net);

int main(int argc, char *argv[])
{

int error=FALSE;
nn main_nn, *net;
time_t now;
long unsigned int start_time, finish_time;

net=&main_nn;

switch (argc){
case 1: /* Default filename to ann.csv */
strcpy(net->training_data_file, "ann.csv");
printf("Using default file - ann.csv\n");
break;
case 2: /* filename specified */
strcpy(net->training_data_file, argv[1]);
printf("Using file - %s\n", net->training_data_file);
break;
default:/* unrecognised cli parameters */
printf("Unrecognised command-line parameters\n");
error=TRUE;
break;
}

while (!error){ /* While we are error free */
start_time=time(&now); /* Start the timer */
initialise_net(net);
}
while(1);
return 0;
}

istartedi

unread,
Jan 19, 2003, 8:17:40 PM1/19/03
to

Allan Bruce <all...@dsl.pipex.com> wrote in message
news:3e2b345b$0$221$cc9e...@news.dial.pipex.com...

> Hi there, can anybody please tell me why I get an error with the
following?
> Thanks
> Allan

What is the input, and what is the error?

[snip]


>
> switch (argc){
> case 1: /* Default filename to ann.csv */
> strcpy(net->training_data_file, "ann.csv");
> printf("Using default file - ann.csv\n");
> break;
> case 2: /* filename specified */
> strcpy(net->training_data_file, argv[1]);

I hope this isn't exposed to the network. Looks like a buffer overflow
waiting to happen.

[snip]
> }
> while(1);
> return 0;

OK, ummm... is this some kind of multithreaded app that exits when all the
threads exit? Unfortunately that would be off-topic here, so if that's
where the problem is you need to find a group related to your system.

> }
>

--$teve


Jens.T...@physik.fu-berlin.de

unread,
Jan 19, 2003, 8:11:24 PM1/19/03
to
Allan Bruce <all...@dsl.pipex.com> wrote:
> Hi there, can anybody please tell me why I get an error with the following?

> #include<stdio.h>


> #include<time.h> /*required for time functions */
> #include<stdlib.h>
> #include<math.h> /*required for maths functions */

> struct neural_net_structure{
<parts snipped>

> char *training_data_file; /* File holding all training data */

<parts snipped>

> };
> typedef struct neural_net_structure nn; /* Now use nn to create a new neural
> network */

<parts snipped>


> int main(int argc, char *argv[])
> {
> int error=FALSE;
> nn main_nn, *net;
> time_t now;
> long unsigned int start_time, finish_time;
> net=&main_nn;
>
> switch (argc){
> case 1: /* Default filename to ann.csv */
> strcpy(net->training_data_file, "ann.csv");

net->training_data_file is just a char pointer that hasn't been
initialized yet and thus is pointing to a random place in memory.
You have first to allocate enough memory for the name you want to
strcpy() to it, e.g. by

if ( ( net->training_data_file = malloc( 8 ) ) == NULL )
{
fprintf( stderr, "malloc() failure.\n" );
exit( EXIT_FAILURE );
}

and only then do the strcpy().

Since you seem to be using just a literal string you could also use

net->training_data_file = "ann.csv";

unless you plan to change the string sometime later (but in this case
you better make 'training_data_file' a 'const char*').

Regards, Jens
--
_ _____ _____
| ||_ _||_ _| Jens.T...@physik.fu-berlin.de
_ | | | | | |
| |_| | | | | | http://www.physik.fu-berlin.de/~toerring
\___/ens|_|homs|_|oerring

pete

unread,
Jan 19, 2003, 8:17:29 PM1/19/03
to
Allan Bruce wrote:
>
> Hi there, can anybody please tell me why I get an error with the following?
> Thanks
> Allan
>
> #include<stdio.h>
> #include<time.h> /*required for time functions */
> #include<stdlib.h>
> #include<math.h> /*required for maths functions */

#include <string.h> /* required for strcpy */

> #define PI
> (double)3.141592653589793238462643383279502884197169399675105820975

There needs to be a backslash after PI
#define PI \

and where the hell did you get the idea that the next digit
after 3.141592653589793238462643383279502884197169399
is 6 ?

--
pete

those who know me have no need of my name

unread,
Jan 19, 2003, 8:19:05 PM1/19/03
to
in comp.lang.c i read:

>Hi there, can anybody please tell me why I get an error with the following?

please don't multi-post. [already answered in alt.comp.lang.learn.c-c++]

--
bringing you boring signatures for 17 years

Martin Ambuhl

unread,
Jan 19, 2003, 10:56:33 PM1/19/03
to
Allan Bruce wrote:
> Hi there, can anybody please tell me why I get an error with the following?
> Thanks

Because you did not #include <string.h> and in foolishly trying to use more
precision than an double has on any real-world machine and introducing an
unnecessary cast, you ended up define PI to be an empty string.

1a3,3
> #include <string.h> /* mha */
31,33c32,32
< #define PI
< (double)3.141592653589793238462643383279502884197169399675105820975
---
> #define 3.1416926535897832385

Jack Klein

unread,
Jan 19, 2003, 11:19:28 PM1/19/03
to
On Sun, 19 Jan 2003 23:27:24 -0000, "Allan Bruce"
<all...@dsl.pipex.com> wrote in comp.lang.c:

> Hi there, can anybody please tell me why I get an error with the following?
> Thanks
> Allan

I just provided a detailed answer to your question and pointed out
problems in your code in the newsgroup alt.comp.lang.learn.c-c++.

If you are going to post an article to more than one newsgroup, after
making sure it is appropriate in all of those groups, the proper
method is to cross post it, not post separate individual messages to
different groups.

People who read your message here will not see replies, including
mine, from alt.comp.lang.learn.c-c++, unless they happen to read both
groups. Likewise many people who see your message there might not see
replies here.

--
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++ ftp://snurse-l.org/pub/acllc-c++/faq

CBFalconer

unread,
Jan 19, 2003, 11:23:29 PM1/19/03
to
Allan Bruce wrote:
>
> can anybody please tell me why I get an error with the following?

... snip code ...

Well, I got:

[1] c:\c\junk>gcc junk.c
junk.c:34: parse error before "double"
junk.c:44: warning: ISO C does not allow extra `;' outside of a
function
junk.c: In function `main':
junk.c:62: `FALSE' undeclared (first use in this function)
junk.c:62: (Each undeclared identifier is reported only once
junk.c:62: for each function it appears in.)
junk.c:71: warning: implicit declaration of function `strcpy'
junk.c:80: `TRUE' undeclared (first use in this function)
junk.c:65: warning: unused variable `finish_time'

Now why couldn't you do that yourself?

--
Chuck F (cbfal...@yahoo.com) (cbfal...@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


E. Gibbons

unread,
Jan 20, 2003, 12:25:08 AM1/20/03
to
In article <3e2b345b$0$221$cc9e...@news.dial.pipex.com>,

Allan Bruce <all...@dsl.pipex.com> wrote:
>
> int total_layers; /* total layers specified by user */
> int total_neurons; /* total number of neurons in net */

I'd just like to share that I initially misread "layers" as "lawyers", and
that, in company with "neurons" and the mention of "net", made me think
this was a program to calculate the drop in intelligence on the Net as
increasing numbers of lawyers get AOL accounts, a la the old chestnut,
num_internet_users * intelligence_per_user = constant.

--Ben

--

Savio Sena

unread,
Jan 24, 2003, 3:27:38 AM1/24/03
to
Jens.T...@physik.fu-berlin.de wrote:
> Allan Bruce <all...@dsl.pipex.com> wrote:
>> Hi there, can anybody please tell me why I get an error with the following?
[snipped for the sake of sanity]

> You have first to allocate enough memory for the name you want to
> strcpy() to it, e.g. by

> if ( ( net->training_data_file = malloc( 8 ) ) == NULL

You are calling strcpy() using argv[1] as the second argument - my
advices are:

1. use strncpy() instead, its safer. ask youself what happens if i
malloc(8) bytes and then call the program like.. ./a.out
"somebigstringthatgoonacrashyourprogram". there is no problem
if you use strncpy(ptr, argv[1], 8);.
2. when you call malloc make sure that you are allocating the
right size (strlen(argv[1]) + 1, or strlen("ann.csv") + 1 for
example), *and* if possible, call calloc() to make sure that
your allocated memory is clean, so if you use less space than
you allocated you wont have trash in the rest of the
memory. Dont forget to check for errors (if (ptr == NULL) {
exit(1) })! :-)

regards,

/savio

Al Bowers

unread,
Jan 24, 2003, 8:22:38 AM1/24/03
to

Savio Sena wrote:


> You are calling strcpy() using argv[1] as the second argument - my
> advices are:
>
> 1. use strncpy() instead, its safer. ask youself what happens if i
> malloc(8) bytes and then call the program like.. ./a.out
> "somebigstringthatgoonacrashyourprogram". there is no problem
> if you use strncpy(ptr, argv[1], 8);.

Assuming ptr is a char array declared:
char ptr[8];

You have a problem here if you attempt to use ptr as a string.
Ex. fopen(ptr,"r"); will fail.

The char array ptr points has the characters:
's' 'o' 'm' 'e' 'b' 'i' 'g' 's'
You need to avouch the nul terminating char with,
in this case,
ptr[7] = '\0';

---
Al Bowers
Tampa, FL. USA
abo...@combase.com
http://www.geocities.com/abowers822
comp.lang.c

Dan Pop

unread,
Jan 24, 2003, 10:45:29 AM1/24/03
to


>
>Savio Sena wrote:
>
>
>> You are calling strcpy() using argv[1] as the second argument - my
>> advices are:
>>
>> 1. use strncpy() instead, its safer. ask youself what happens if i
>> malloc(8) bytes and then call the program like.. ./a.out
>> "somebigstringthatgoonacrashyourprogram". there is no problem
>> if you use strncpy(ptr, argv[1], 8);.
>
>Assuming ptr is a char array declared:
>char ptr[8];
>
>You have a problem here if you attempt to use ptr as a string.
>Ex. fopen(ptr,"r"); will fail.
>
>The char array ptr points has the characters:
>'s' 'o' 'm' 'e' 'b' 'i' 'g' 's'
>You need to avouch the nul terminating char with,
>in this case,
>ptr[7] = '\0';

I don't think that this is the proper solution for the problem. If the
user typed "somebigstringthatgoonacrashyourprogram", then this is what
he expects the program to use, and certainly not "somebig".

So, the code should check the length of argv[1] and produce an error
message if it exceeds the maximum allowed value. After that, there is
no problem with using strcpy, since you know that the string will fit
into the allocated space.

The cases where strncpy is the right solution are few and far between.
I've used it only when the specs asked for non-null terminated strings
if the string was as large as the array that had to receive it.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Dan...@ifh.de

Al Bowers

unread,
Jan 25, 2003, 12:05:22 AM1/25/03
to

Dan Pop wrote:


>
> I don't think that this is the proper solution for the problem. If the
> user typed "somebigstringthatgoonacrashyourprogram", then this is what
> he expects the program to use, and certainly not "somebig".
>
> So, the code should check the length of argv[1] and produce an error
> message if it exceeds the maximum allowed value. After that, there is
> no problem with using strcpy, since you know that the string will fit
> into the allocated space.


I agree that his would be best advisible solution to this problem.

>
> The cases where strncpy is the right solution are few and far between.
> I've used it only when the specs asked for non-null terminated strings
> if the string was as large as the array that had to receive it.

This seems to be a paradox. I thought the common definition of a string
is a character array that is nul terminated.

If you just want to copy arbitary bytes, as opposed to strings, to the fill the
array, usually memcpy is more appropriate.

Dan Pop

unread,
Jan 27, 2003, 7:50:21 AM1/27/03
to
In <3E321B12...@combase.com> Al Bowers <abo...@combase.com> writes:

>Dan Pop wrote:
>
>> The cases where strncpy is the right solution are few and far between.
>> I've used it only when the specs asked for non-null terminated strings
>> if the string was as large as the array that had to receive it.
>
>This seems to be a paradox. I thought the common definition of a string
>is a character array that is nul terminated.

Yes, this is the definition of a proper C string. Yet, there are cases
when the "improper" strings described above are used.

>If you just want to copy arbitary bytes, as opposed to strings, to the fill the
>array, usually memcpy is more appropriate.

No, I don't want to copy arbitrary bytes, I want to copy the kind of
"strings" strncpy was actually designed for. I have already described
a real life application (the original Unix filesystem) of such strings.
Even modern Unix systems use them, e.g. in the utmp structure. From the
Linux utmp man page:

struct utmp {
short ut_type; /* type of login */
pid_t ut_pid; /* pid of login process */
char ut_line[UT_LINESIZE]; /* device name of tty - "/dev/" */
char ut_id[4]; /* init id or abbrev. ttyname */
char ut_user[UT_NAMESIZE]; /* user name */
char ut_host[UT_HOSTSIZE]; /* hostname for remote login */
struct exit_status ut_exit; /* The exit status of a process
marked as DEAD_PROCESS. */
long ut_session; /* session ID, used for windowing*/
struct timeval ut_tv; /* time entry was made. */
int32_t ut_addr_v6[4]; /* IP address of remote host. */
char pad[20]; /* Reserved for future use. */
};

This structure gives the name of the special file associ­
ated with the user's terminal, the user's login name, and
the time of login in the form of time(2). String fields
are terminated by '\0' if they are shorter than the size
of the field. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^

If the maximum size of the "string" is known, this is a common trick for
gaining one extra character.

Al Bowers

unread,
Jan 27, 2003, 3:04:57 PM1/27/03
to

Dan Pop wrote:

> In <3E321B12...@combase.com> Al Bowers <abo...@combase.com> writes:

>>This seems to be a paradox. I thought the common definition of a string
>>is a character array that is nul terminated.
>>
>
> Yes, this is the definition of a proper C string. Yet, there are cases
> when the "improper" strings described above are used.


Although it does not matter, I am not sure of what context you are
are suggesting. Perhaps you are saying that the term "non-null strings"
is used in descriptive terminology. There are probably cases where
this diction is used but I've never noticed it in the Standard.
Nor, am I not sure who you are quoting. Certainly the quote "improper"
did not come from me on this topic. I am just suggesting that the use
of strings, non-nulled qualified, can be puzzling.


>>If you just want to copy arbitary bytes,

>No, I don't want to copy arbitrary bytes,

.....snip.......


> This structure gives the name of the special file associ­
> ated with the user's terminal, the user's login name, and
> the time of login in the form of time(2). String fields
> are terminated by '\0' if they are shorter than the size
> of the field. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> ^^^^^^^^^^^^^


Yes, this depiction should call for the use of function strncpy.

But here you have synopsized in more detail than a more prior post.
In that post, in regards to the spec, you said, "I've used it


only when the specs asked for non-null terminated strings
if the string was as large as the array that had to receive it."

Due in part from the antilogy, I thought you were referring
that in the copy, the source and destination as being
non-null terminated char arrays, thus the copying of arbitrary
bytes and the call for function memcpy.

With my misunderstanding rectified, it appears we are of a common
opinion, in that the need for the function strncpy is rare.

--------

Reply all
Reply to author
Forward
0 new messages