[Info-vax] calloc fails with access violation
Jim Duff
spam.this at 127.0.0.1
Tue Aug 25 17:36:44 EDT 2009
Jose Cuevas wrote:
> On Aug 24, 1:45 pm, VAXman- @SendSpamHere.ORG wrote:
>> In article <aecec9c9-3fe0-4b76-b37a-c5cd9ebf5... at a13g2000yqc.googlegroups.com>, Jose Cuevas <jcue... at mac.com> writes:
>>
>>
>>
>>
>>
>>> 1. We have a problem with a fairly simple library written in C that
>>> gets called from Cobol.
>>> The C library is used to PUSH data generated by the Cobol application
>>> over HTTP POST using sockets.
>>> We are getting an access violation (a crash) on calls to calloc() of
>>> insignificant size. While at first we thought it was on a particular
>>> record we then found that it is a far more inconsistent.
>>> The C code runs fine when tested on a unix machine.
>>> 2. Unrelated question: if we send a variable from a record structure
>>> to a C function we get an access violation. So far the only workaround
>>> we found is to move variables to one defined at the working-storage.
>>> Any ideas on how to use record variables as parameters for C
>>> functions?
>> Don't post a snippet of the code which you are questioning -- hint,
>> hint.
Perhaps you should be a little more explicit, Brian. Perhaps asking for
a snippet of code that *actually demonstrates the problem* (unlike the
code that's posted below) would be a good idea ;-)
>>
>> If you are calling C routines from Cobol, make certain that you are
>> passing the data properly. Strings, for example, in COBOL are typ-
>> ically passed by DESCRIPTOR whereas C will pass references to null-
>> terminated byte streams. I would expect any C code to get rather
>> upset if passed a string DESCRIPTOR in lieu of a reference to null-
>> terminated streams.
>>
>> --
>> VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG
>>
>> http://www.quirkfactory.com/popart/asskey/eqn2.png
>>
>> "Well my son, life is like a beanstalk, isn't it?"
>
> 1. The code fails randomly at different points that use calloc. For
> example at the C function.
>
> char *ckGetCobolString(char *sIn){
> int i = 0;
> char *s = calloc(strlen(sIn), sizeof(char));
> strcpy(s, sIn);
> for(i=strlen(sIn)-1;i>=0; i--){
> /*skip whites*/
> if(s[i] != ' ') break;
> }
> s[i+1] = '\0';
> return s;
> }
>
> In the above code I can printf the pointer sIn and do a strlen without
> problems, it is not the strlen crashing. If we use static strings
> (char arrays) in C the code works. But thats not an option as the size
> of data is unknown.
>
> In Cobol we use:
> DATA DIVISION.
> FILE SECTION.
> 05 E0-NOMBRE-COMPLETO.
> 10 E0-PATERNO PICTURE X(15).
> 10 E0-MATERNO PICTURE X(15).
> 10 E0-NOMBRE PICTURE X(14).
> 10 E0-INICIAL PICTURE X(01).
> ....
> WORKING-STORAGE SECTION.
> 01 WS-NOMBRE-COMPLETO PICTURE X(45).
> ....
> PROCEDURE DIVISION.
> CALL "ckDefineField" USING "name".
> ....
> MOVE E0-NOMBRE-COMPLETO TO WS-NOMBRE-COMPLETO.
> CALL "ckSetField" USING "name", WS-NOMBRE-COMPLETO.
>
>[snip]
The code above does not demonstrate your problem as function
ckGetCobolString() is never called from your COBOL code. I don't know
why you are using calloc in preference to malloc. malloc takes as an
argument a number of chars to allocate. Specifying calloc with sizeof
(char) just makes the code more verbose.
Here is an example of passing strings between COBOL and C. I don't know
what your C code is attempting to do. Let's just assume you are for
some reason mallocing some memory, copying the string that was passed in
by COBOL, printing the string, printing the trimmed of whitespace
string, and freeing the memory again. Hopefully this will point you in
the right direction.
C code:
#include <stdio.h>
#include <stdlib.h>
#include <ssdef.h>
#include <string.h>
#include <descrip.h>
#include <assert.h>
#include <ctype.h>
extern int copy_and_print (const struct dsc$descriptor_s const *in_d) {
char *p = NULL;
int i;
assert (in_d != NULL);
assert (in_d->dsc$a_pointer != NULL);
if (in_d->dsc$w_length >= 1) {
p = malloc (in_d->dsc$w_length + 1);
if (p == NULL) {
fprintf (stderr, "Could not allocate mem!\n");
return SS$_INSFMEM;
}
strncpy (p, in_d->dsc$a_pointer, in_d->dsc$w_length);
printf ("Original string is \"%s\"\n", p);
for (i = strlen (p) - 1; i > 0; i--) {
if (!isspace (p[i])) {
p[++i] = '\0';
break;
}
}
printf ("Modified string is \"%s\"\n", p);
free (p);
}
return SS$_NORMAL;
}
COBOL code:
identification division.
program-id. test-c-call.
environment division.
data division.
working-storage section.
01 test_string pic x(45).
01 ret_status pic s9(09) comp.
procedure division.
0-begin.
move "Jose" to test_string.
call "copy_and_print" using by descriptor test_string
giving ret_status.
if ret_status is failure
call "lib$signal" using by value ret_status.
0-end.
stop run.
Jim.
--
www.eight-cubed.com
More information about the Info-vax
mailing list