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

Weird stuff with char pointers, need someone to troubleshoot

Hi,

I am working on a project for school and I am trying to get my head
around something weird. I have a function setup which is used to get
an input from stdin and a piece of memory is created on the heap using
malloc. This input is then run through a regex and another test. The
result is passed back as a char pointer to the program for further
processing

The first time I call this function, it performs normally. However,
after that if I call it in succession, the contents of the char array
behave strangely. Example, if I input a set of 3 numbers like "345" on
the first try, the strlen function returns the correct number 3 once
main has control of the program flow. But then if I go through the
loop again and type in 3 more numbers, the resulting array now has a
strlen of 4. Before I get the new number, I free the memory of the
char pointer that was used to hold the string. If I loop through this
over and over, the size of the strlen result changes and when I print
out the ASCII values of the string, it shows alot of weird characters
are showing up in there.

I need some help, I'm stuck. Below is the entire code I'm working with
(including printf statements for troubleshooting purposes).

David

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <regex.h>

void jsw_flush ( void ) /*from http://c-for-dummies.com/faq/*/
{
int ch; /* getchar returns an int */

/* Read characters until there are none left */
do
ch = getchar();
while ( ch != EOF && ch != '\n') ;
clearerr ( stdin ); /* Clear EOF state */
}

/* match input against regex */
int match(const char *string, char *pattern)
{
int status;
regex_t re;

if(regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0)
{ return 0; }

status = regexec(&re, string, (size_t)0, NULL, 0);

regfree(&re);

if(status != 0)
{ return 0; }

return 1;
}

/* get input from user, discard excess input */
char * inputFlush()
{
char temp[52];
char * input = NULL;
int len = 0;
fgets(temp, sizeof(temp), stdin);
temp[strlen(temp)-1] = '\0'; /* trim off last character */
len = strlen(temp);
printf("len: %i\n", len);
input = (char *)malloc(sizeof(char) * len);
strncpy(input, temp, len);
printf("input is %s\n", input);
jsw_flush();
return input;
}
int main()
{

int error = 1, number = 0, i = 0;
char * numInput1;
char * numPattern = "^-?[0-9]{1,5}$";
/* input - numbers */
while (number != -1)
{
printf("numInput1 is: %p\n", numInput1);
printf("Enter a number: ");
numInput1 = inputFlush();
printf("numInput1 is: %p\n", numInput1);
for (i=0; i < strlen(numInput1); i++)
printf("%x\n", numInput1[i]);
printf("Strlen(numInput1) %i\n", strlen(numInput1));
printf("numInput1 contains: %s\n", numInput1);
error = match(numInput1, numPattern); /* run regex against number
input */
printf("error: %i\n", error);
if (!error) /* num contains illegal characters */
printf("number has illegal characters\n");
if (error)
{
number = atol(numInput1); /* convert string to int */
printf("number value: %i\n", number);
if (number <= 32767 && number >= -32768) /* check to see if in
valid range */
printf("number is in valid range\n"); /* int OK move on */
else
printf("number is not in range\n"); /* bad int, get another */
}
free(numInput1);
numInput1 = NULL;
}
}

Feb 23 '07 #1
7 1979
Let me post a version of this without the first function that was
included in the original post. I think that one probably is not needed
for this task.

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <regex.h>

/* match input against regex */
int match(const char *string, char *pattern)
{
int status;
regex_t re;

if(regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0)
{ return 0; }

status = regexec(&re, string, (size_t)0, NULL, 0);

regfree(&re);

if(status != 0)
{ return 0; }

return 1;
}

/* get input from user, discard excess input */
char * inputFlush()
{
char temp[52];
char * input = NULL;
int len = 0;
fgets(temp, sizeof(temp), stdin);
temp[strlen(temp)-1] = '\0';
len = strlen(temp);
printf("len: %i\n", len);
input = (char *)malloc(sizeof(char) * len);
strncpy(input, temp, len);
printf("input is %s\n", input);
return input;
}
int main()
{

int error = 0, number = 0, i = 0;
char * numInput1;
char * numPattern = "^[-+]?[0-9]{1,5}$";
/* input - numbers */
while (number != -1)
{
printf("Enter a number: ");
numInput1 = inputFlush();
for (i=0; i < strlen(numInput1); i++)
printf("%x\n", numInput1[i]);
printf("strlen(numInput1) %i\n", strlen(numInput1));
error = match(numInput1, numPattern);
printf("error: %i\n", error);
if (!error)
printf("number has illegal characters\n");
if (error)
{
number = atol(numInput1);
printf("number value: %i\n", number);
if (number <= 32767 && number >= -32768)
printf("number is in valid range\n");
else
printf("number is not in range\n");
}
free(numInput1);
numInput1 = NULL;
}
}

Feb 23 '07 #2
Ico
dt*******@gmail.com wrote:
Hi,

I am working on a project for school and I am trying to get my head
around something weird. I have a function setup which is used to get
an input from stdin and a piece of memory is created on the heap using
malloc. This input is then run through a regex and another test. The
result is passed back as a char pointer to the program for further
processing

The first time I call this function, it performs normally. However,
after that if I call it in succession, the contents of the char array
behave strangely. Example, if I input a set of 3 numbers like "345" on
the first try, the strlen function returns the correct number 3 once
main has control of the program flow. But then if I go through the
loop again and type in 3 more numbers, the resulting array now has a
strlen of 4. Before I get the new number, I free the memory of the
char pointer that was used to hold the string. If I loop through this
over and over, the size of the strlen result changes and when I print
out the ASCII values of the string, it shows alot of weird characters
are showing up in there.

I need some help, I'm stuck. Below is the entire code I'm working with
(including printf statements for troubleshooting purposes).

David

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <regex.h>
(people will complain about this header on comp.lang.c)
void jsw_flush ( void ) /*from http://c-for-dummies.com/faq/*/
{
int ch; /* getchar returns an int */
[snipped somde code]
/* get input from user, discard excess input */
char * inputFlush()
{
char temp[52];
char * input = NULL;
int len = 0;
fgets(temp, sizeof(temp), stdin);
temp[strlen(temp)-1] = '\0'; /* trim off last character */
len = strlen(temp);
printf("len: %i\n", len);
input = (char *)malloc(sizeof(char) * len);
Rethink what you are doing here. C-strings need a terminating 0.

--
:wq
^X^Cy^K^X^C^C^C^C
Feb 23 '07 #3
dt*******@gmail.com wrote:
Let me post a version of this without the first function that was
included in the original post. I think that one probably is not needed
for this task.

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <regex.h>

/* match input against regex */
int match(const char *string, char *pattern)
{
int status;
regex_t re;

if(regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0)
{ return 0; }

status = regexec(&re, string, (size_t)0, NULL, 0);

regfree(&re);

if(status != 0)
{ return 0; }

return 1;
}

/* get input from user, discard excess input */
char * inputFlush()
{
char temp[52];
char * input = NULL;
int len = 0;
fgets(temp, sizeof(temp), stdin);
Check the fgets call. It can return NULL when an error occurs or end-
of-file is encountered.
temp[strlen(temp)-1] = '\0';
Why? fgets always terminates it's output with a null character. You're
overwriting the last non-null character here.
len = strlen(temp);
strlen returns the length of a string *without* counting it's
terminating null character.
printf("len: %i\n", len);
input = (char *)malloc(sizeof(char) * len);
Don't cast the return value of malloc. It can hide certain mistakes.
I'd write the above as:

input = malloc(len+1 * sizeof *input);

Notice that I added one to len for accomodating a null character.
Otherwise what's left isn't a C string.
strncpy(input, temp, len);
Supply len+1 here too.
printf("input is %s\n", input);
The %s specifier expects a null terminated string. You're passing an
array of char without a null terminator.
return input;
}
int main()
{

int error = 0, number = 0, i = 0;
char * numInput1;
char * numPattern = "^[-+]?[0-9]{1,5}$";
/* input - numbers */
while (number != -1)
{
printf("Enter a number: ");
Terminate output with a newline or call fflush(stdout) immediatly
afterwards.
numInput1 = inputFlush();
for (i=0; i < strlen(numInput1); i++)
printf("%x\n", numInput1[i]);
printf("strlen(numInput1) %i\n", strlen(numInput1));
Why not compute the string length once and store it, instead of
calling strlen again and again?
error = match(numInput1, numPattern);
printf("error: %i\n", error);
if (!error)
printf("number has illegal characters\n");
if (error)
{
number = atol(numInput1);
I'd advise you to use strtol here, since it has better error checking
and reporting.
printf("number value: %i\n", number);
if (number <= 32767 && number >= -32768)
Why code in this non-portable construct. Just compare with INT_MAX and
INT_MIN defined in limits.h. The range of integers, (and floats), will
vary from platform to platform. Each implementation defines the ranges
in limits.h and float.h. Using those macros is more robust than
hardcoding values specific for a platform.
printf("number is in valid range\n");
else
printf("number is not in range\n");
}
free(numInput1);
numInput1 = NULL;
}
Return a value from main with a return statement.
}
Feb 23 '07 #4
On Feb 23, 12:43 am, Ico <use...@zeev.nlwrote:
>
[snipped some code]
/* get input from user, discard excess input */
char * inputFlush()
{
char temp[52];
char * input = NULL;
int len = 0;
fgets(temp, sizeof(temp), stdin);
temp[strlen(temp)-1] = '\0'; /* trim off last character */
len = strlen(temp);
printf("len: %i\n", len);
input = (char *)malloc(sizeof(char) * len);

Rethink what you are doing here. C-strings need a terminating 0.

--
:wq
^X^Cy^K^X^C^C^C^C
Thanks, that fixed it for me.

David

Feb 23 '07 #5

"santosh" <sa*********@gmail.comwrote in message
news:11**********************@v33g2000cwv.googlegr oups.com...
dt*******@gmail.com wrote:
>Let me post a version of this without the first function that was
included in the original post. I think that one probably is not needed
for this task.

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <regex.h>

/* match input against regex */
int match(const char *string, char *pattern)
{
int status;
regex_t re;

if(regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0)
{ return 0; }

status = regexec(&re, string, (size_t)0, NULL, 0);

regfree(&re);

if(status != 0)
{ return 0; }

return 1;
}

/* get input from user, discard excess input */
char * inputFlush()
{
char temp[52];
char * input = NULL;
int len = 0;
fgets(temp, sizeof(temp), stdin);

Check the fgets call. It can return NULL when an error occurs or end-
of-file is encountered.
>temp[strlen(temp)-1] = '\0';

Why? fgets always terminates it's output with a null character. You're
overwriting the last non-null character here.
>len = strlen(temp);

strlen returns the length of a string *without* counting it's
terminating null character.
>printf("len: %i\n", len);
input = (char *)malloc(sizeof(char) * len);

Don't cast the return value of malloc. It can hide certain mistakes.
I'd write the above as:

input = malloc(len+1 * sizeof *input);

Notice that I added one to len for accomodating a null character.
Otherwise what's left isn't a C string.
No, you didn't. You added (1 * sizeof(*input)) to len
>
>strncpy(input, temp, len);

Supply len+1 here too.
>printf("input is %s\n", input);

The %s specifier expects a null terminated string. You're passing an
array of char without a null terminator.
>return input;
}
int main()
{

int error = 0, number = 0, i = 0;
char * numInput1;
char * numPattern = "^[-+]?[0-9]{1,5}$";
/* input - numbers */
while (number != -1)
{
printf("Enter a number: ");

Terminate output with a newline or call fflush(stdout) immediatly
afterwards.
>numInput1 = inputFlush();
for (i=0; i < strlen(numInput1); i++)
printf("%x\n", numInput1[i]);
printf("strlen(numInput1) %i\n", strlen(numInput1));

Why not compute the string length once and store it, instead of
calling strlen again and again?
>error = match(numInput1, numPattern);
printf("error: %i\n", error);
if (!error)
printf("number has illegal characters\n");
if (error)
{
number = atol(numInput1);

I'd advise you to use strtol here, since it has better error checking
and reporting.
>printf("number value: %i\n", number);
if (number <= 32767 && number >= -32768)

Why code in this non-portable construct. Just compare with INT_MAX and
INT_MIN defined in limits.h. The range of integers, (and floats), will
vary from platform to platform. Each implementation defines the ranges
in limits.h and float.h. Using those macros is more robust than
hardcoding values specific for a platform.
>printf("number is in valid range\n");
else
printf("number is not in range\n");
}
free(numInput1);
numInput1 = NULL;
}

Return a value from main with a return statement.
>}
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Aero Stability and Controls Computing
Feb 23 '07 #6
Fred Kleinschmidt wrote:
"santosh" <sa*********@gmail.comwrote in message
news:11**********************@v33g2000cwv.googlegr oups.com...
dt*******@gmail.com wrote:
<snip>
input = (char *)malloc(sizeof(char) * len);
Don't cast the return value of malloc. It can hide certain mistakes.
I'd write the above as:

input = malloc(len+1 * sizeof *input);

Notice that I added one to len for accomodating a null character.
Otherwise what's left isn't a C string.

No, you didn't. You added (1 * sizeof(*input)) to len
Thanks for spotting that. Amazing how it could've slipped past me.

<snip>

Feb 23 '07 #7
"santosh" <sa*********@gmail.comwrites:
dt*******@gmail.com wrote:
[...]
> fgets(temp, sizeof(temp), stdin);

Check the fgets call. It can return NULL when an error occurs or end-
of-file is encountered.
> temp[strlen(temp)-1] = '\0';

Why? fgets always terminates it's output with a null character. You're
overwriting the last non-null character here.
[...]

The string produced by fgets() typically ends in a '\n' character
(just before the '\0'). Probably the OP wanted the string without the
'\n' (<OT>like Perl's "chomp"</OT>). But he should check that the
character is a '\n' before stepping on it; it won't contain a '\n' if
fgets() reads the specified number of characters before reaching the
end of the input line.

--
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.
Feb 23 '07 #8

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

Similar topics

2
by: Maximus | last post by:
Hi, I'm not verry good at c++ but I was asking myself this question... Could it be possible to store a variable into a file and load it back into the same variable? What I would like to do is save...
11
by: Anon Email | last post by:
Hey people, This looks really weird. I can't make sense of it. Is this a mistake? Can anyone help? IStack const & GetStack () const; Cheers,
11
by: Mr. Berserker | last post by:
I was posting stuff to a mailing list when a friend, Prof. Corbessero and I came up with this one. Perhaps you can help resolve this, or add anything else worth knowing?? Maybe it should be added...
8
by: G Patel | last post by:
Can people please comment on the layout/style of my problem? The major issue I had was the layout. I ended up having to put a relatively large switch statement, inside an if statement, which is...
9
by: Frederick Gotham | last post by:
I think someone posted elsewhere on the group that we must be able to address at least 65 535 bytes in C... ? (Or something along those lines). A 16-Bit unsigned integer type has 65 536 unique...
5
by: jerry | last post by:
I need to modify the code of a command-line tool. The source code starts out like this: int main(int argc, char *argv) { int ch, A, B ; while ((ch = getopt(argc, argv, "AB")) != -1)...
18
by: atv | last post by:
at least to me it is. I can't figure out for the life what it is i'm doing wrong here. i have a function called assign_coordinate. usually, i pass a malloced pointer to it, then individual...
1
by: cjordan | last post by:
Hi everyone. I'm new here, and I think I've got a pretty unique problem (haven't found any solution to this anywhere else), but I'm hoping that someone here can help me. To be honest, I'm not a...
2
by: Philluminati | last post by:
I'm a bit of a python newbie and I need to wrap a C library. I can initialise the library using CDLL('mcclient.so') and I can call functions correctly inside the library but I need to invoke...
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: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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
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,...
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
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.