返回时,C字符串函数参数为NULL

时间:2013-09-28 04:36:47

标签: c arrays string pointers

我正在处理的函数需要两个字符串作为输入(以及一些其他参数),并在输出中返回两个不同的字符串。我认为最合乎逻辑的做法是为错误返回int并将两个指针作为参数添加到C字符串中。这就是我这样做的方式:

int annealc(const char *sequence1, const char *sequence2, float startTemp, float endTemp, float tempStep, int cycles, char *retVal1, char *retVal2, int *score)
{
    ...
    retVal1 = malloc(MAX(len1, len2));
    retVal2 = malloc(MAX(len1, len2));
    ...
    strcpy(retVal1, sequence1);
    strcpy(retVal2, sequence2);
    ...
    //Somewhere along the line retVal is exchanged for another string
    free(retVal1);
    free(retVal2);
    retVal1 = currentSeq1;
    retVal2 = currentSeq2;
    ...
    *score = bestScore;

    return 0;
}

//Intended use:
int error = annealc(content1, content2,
                    30, 5, 1, 5,
                    alignment1, alignment2, &score);

我认为我没有正确使用指针的语法,因为当函数返回时,alignment1alignment2中没有任何值。那么,我做错了什么?

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

你是对的,你没有使用正确的参数类型。你想要你在函数中设置的指针,并期望在返回后输入值作为指针的指针。

类似的东西。

int annealc
(
    const char *sequence1, 
    const char *sequence2, 
    float startTemp, 
    float endTemp, 
    float tempStep, 
    int cycles, 
    char **retVal1,
    char **retVal2, 
    int *score
)
{
    ...
    *retVal1 = malloc(MAX(len1, len2));
    *retVal2 = malloc(MAX(len1, len2));
    ...
    strcpy(*retVal1, sequence1);
    strcpy(*retVal2, sequence2);
    ...
    //Somewhere along the line retVal is exchanged for another string
    free(*retVal1);
    free(*retVal2);
    *retVal1 = currentSeq1;
    *retVal2 = currentSeq2;
    ...
    *score = bestScore;

    return 0;
}

//Intended use:
int error = annealc(content1, content2,
                    30, 5, 1, 5,
                    &alignment1, &alignment2, &score);

原因是在你的版本中,参数retVal1和retVal2只是作为char指针键入。这意味着这些变量只保存一个可以通过使用* retVal1或* retVal2来解除引用的地址值来检查或修改该地址的字符。

当你将它们键入指针指向时,它们会保存对其他指针的地址的引用。取消引用指向指针的指针允许您检查或修改另一个指针引用的地址。

以下示例最能说明这一点:

#include <stdio.h>
#include <string.h>
#include <memory.h>

void sample1(char *inner) 
{
    printf("IN SAMPLE1 BEFORE MALLOC: Address of inner is %p\n", &inner);
    printf("IN SAMPLE1 BEFORE MALLOC: Address held by inner is %p\n", inner);
    printf("IN SAMPLE1 BEFORE MALLOC: The char referenced by inner is %c\n", *inner);

    inner = (char *)malloc(4);
    strcpy(inner, "WXYZ");

    printf("IN SAMPLE1 AFTER MALLOC: Address of inner is %p\n", &inner);
    printf("IN SAMPLE1 AFTER MALLOC: Address held by inner is %p\n", inner);
    printf("IN SAMPLE1 AFTER MALLOC: The char referenced by inner is %c\n\n", *inner);
}

void sample2(char **inner) 
{
    printf("IN SAMPLE2 BEFORE MALLOC: Address of inner is %p\n", &inner);
    printf("IN SAMPLE2 BEFORE MALLOC: Address of the pointer held by inner is %p\n", inner);
    printf("IN SAMPLE2 BEFORE MALLOC: Address of the char referenced by the address held by inner is %p\n", *inner);
    printf("IN SAMPLE2 BEFORE MALLOC: The char referenced by the address held by inner is %c\n\n", **inner);

    *inner = (char *)malloc(sizeof(char));
    **inner = 'W';

    printf("IN SAMPLE2 AFTER MALLOC: Address of inner is %p\n", &inner);
    printf("IN SAMPLE2 AFTER MALLOC: Address of the pointer held by inner is %p\n", inner);
    printf("IN SAMPLE2 AFTER MALLOC: Address of the char referenced by the address held by inner is %p\n", *inner);
    printf("IN SAMPLE2 AFTER MALLOC: The char referenced by the address held by inner is %c\n\n", **inner);
}



int main(int argc, char *argv[])
{
    char myChar = 'A';
    char *outer = &myChar;

    printf("Addres of myChar is %p\n\n", &myChar);

    printf("BEFORE sample1: Address of outer is %p\t\t\t\t\t\tThis is where the variable 'outer' resides in memory.\n", &outer);
    printf("BEFORE sample1: Address of the char held by outer is %p\t\t\t\tThis matches the address of 'myChar' because that is what we set 'outer' to.\n", outer);
    printf("BEFORE sample1: The char referenced by the address held by outer is %c\t\t\tThis is the same as the value held by 'myChar'.\n\n", *outer);

    sample1(outer);

    printf("AFTER sample1: Address of outer is %p\t\t\t\t\t\tThe variable 'outer' is unaffected by the call to sample1.\n", &outer);
    printf("AFTER sample1: Address of the char held by outer is %p\n", outer);
    printf("AFTER sample1: The char referenced by outer is %c\n\n\n", *outer);

    printf("BEFORE sample2: Address of outer is %p\t\t\t\t\t\tThis is all the same as before sample1 since 'outer' was not affected.\n", &outer);
    printf("BEFORE sample2: Address of the char held by outer is %p\n", outer);
    printf("BEFORE sample2: The char referenced by the address held by outer is %c.\n\n", *outer);

    printf("BEFORE sample2: Address of outer is %p\n", &outer);
    printf("BEFORE sample2: Address referenced by outer is %p\n", outer);
    printf("BEFORE sample2: The char referenced by the address held by outer is %c\n\n", *outer);

    sample2(&outer);

    printf("AFTER sample2: Address of outer is %p\t\t\t\t\t\tThe variable 'outer' still resides in the same place in memory; this didn't change.\n", &outer);
    printf("AFTER sample2: Address referenced by outer is %p\t\t\t\t\tThe address held by 'outer' now matches what was assigned inside the call to sample2.\n", outer);
    printf("AFTER sample2: The char referenced by the address held by outer is %c\t\t\t...as well as now references the character 'W' which was stored in the memory allocated inside the call to sample2.\n", *outer);

    return 0;
}

/*
Example Output:

Addres of myChar is 002EFD33

BEFORE sample1: Address of outer is 002EFD24                                            This is where the variable 'outer' resides in memory.
BEFORE sample1: Address of the char held by outer is 002EFD33                           This matches the address of 'myChar' because that is what we set 'outer' to.
BEFORE sample1: The char referenced by the address held by outer is A                   This is the same as the value held by 'myChar'.

IN SAMPLE1 BEFORE MALLOC: Address of inner is 002EFC50
IN SAMPLE1 BEFORE MALLOC: Address held by inner is 002EFD33
IN SAMPLE1 BEFORE MALLOC: The char referenced by inner is A
IN SAMPLE1 AFTER MALLOC: Address of inner is 002EFC50
IN SAMPLE1 AFTER MALLOC: Address held by inner is 0075B0F8
IN SAMPLE1 AFTER MALLOC: The char referenced by inner is W

AFTER sample1: Address of outer is 002EFD24                                             The variable 'outer' is unaffected by the call to sample1.
AFTER sample1: Address of the char held by outer is 002EFD33
AFTER sample1: The char referenced by outer is A


BEFORE sample2: Address of outer is 002EFD24                                            This is all the same as before sample1 since 'outer' was not affected.
BEFORE sample2: Address of the char held by outer is 002EFD33
BEFORE sample2: The char referenced by the address held by outer is A.

BEFORE sample2: Address of outer is 002EFD24
BEFORE sample2: Address referenced by outer is 002EFD33
BEFORE sample2: The char referenced by the address held by outer is A

IN SAMPLE2 BEFORE MALLOC: Address of inner is 002EFC50
IN SAMPLE2 BEFORE MALLOC: Address of the pointer held by inner is 002EFD24
IN SAMPLE2 BEFORE MALLOC: Address of the char referenced by the address held by inner is 002EFD33
IN SAMPLE2 BEFORE MALLOC: The char referenced by the address held by inner is A

IN SAMPLE2 AFTER MALLOC: Address of inner is 002EFC50
IN SAMPLE2 AFTER MALLOC: Address of the pointer held by inner is 002EFD24
IN SAMPLE2 AFTER MALLOC: Address of the char referenced by the address held by inner is 0075B128
IN SAMPLE2 AFTER MALLOC: The char referenced by the address held by inner is W

AFTER sample2: Address of outer is 002EFD24                                             The variable 'outer' still resides in the same place in memory; this didn't change.
AFTER sample2: Address referenced by outer is 0075B128                                  The address held by 'outer' now matches what was assigned inside the call to sample2.
AFTER sample2: The char referenced by the address held by outer is W                    ...as well as now references the character 'W' which was stored in the memory allocated inside the call to sample2.

*/