如何正确使用从函数接收的指针? (在C中)

时间:2017-01-12 21:11:00

标签: c string pointers

我编写了一个名为safecat的函数,它将一个字符串(称为ct)添加到另一个字符串的末尾(称为s)。 然后返回生成的新s

在main函数中,我的任务是检查我的函数是否按预期方式工作,如果是,则打印函数safecat的结果。

我遇到的问题是,当我在主函数中将safecat的返回值分配给另一个char - 字符串(在本例中为str)时,{{1}中的内容来自str的1}}只是垃圾。 我不明白问题出在哪里,如果我只是ct我得到了正确的结果。

在这里,您可以看到我的代码:

printf("%s", safecat(s, ct));

我认为当我将#include <stdio.h> #include <stdlib.h> #include <string.h> char *safecat(char *s, const char *ct); int main() { char s[] = "Twin"; const char ct[] = "Peaks"; char *str = safecat(s, ct); if(str == NULL){ printf("Error in function!"); return 1; } printf("\n%s\n", str); return 0; } char *safecat(char *s, const char *ct){ int i, k, j = 0; int max_count = strlen(s) + strlen(ct) + 1; for(i = strlen(s); i < max_count; i = i + sizeof(char)){ *(s + i) = (char *) malloc((strlen(s) + strlen(ct) + 1) * sizeof(char)); if(!(s + i)){ for(k = strlen(s) / sizeof(char); k < i; k++){ free(*(s + k)); } return NULL; } *(s + i) = *(ct + j); j++; } return s; } 分配给safecat时会发生错误。 当我打印str时,我得到“str”而不是“TwinP' a”。

感谢您的帮助!

4 个答案:

答案 0 :(得分:2)

您无法更改数组的大小

char s[] = "Twin";

在使用malloc的函数中。

无论如何这个循环

for(i = strlen(s); i < max_count; i = i + sizeof(char)){
    *(s + i) = (char *) malloc((strlen(s) + strlen(ct) + 1) * sizeof(char));
    if(!(s + i)){
        for(k = strlen(s) / sizeof(char); k < i; k++){
            free(*(s + k));
        }
        return NULL;
    }
    *(s + i) = *(ct + j);
    j++;
}

没有意义。例如,表达式*(s + i)的类型为char,而不是类型char *。而且还不清楚为什么在循环的每次迭代中分配内存。

正确的方法是动态分配一个新数组,其大小等于源数组的大小加一,并复制分配数组中的源数组。

这是一个演示程序,展示了如何完成它。此外,当不再需要阵列时,您应释放已分配的内存。

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

char * safecat(const char *s1, const char *s2)
{
    char *result = malloc(strlen(s1) + strlen(s2) + 1);

    if (result != NULL)
    {
        char *p = result;

        while (*s1) *p++ = *s1++;
        do { *p++ = *s2; } while (*s2++);
    }

    return result;
}

int main( void )
{
    char s[] = "Twin";
    char ct[] = "Peaks";

    char *str = safecat(s, ct);

    if (str == NULL) 
    {
        puts("Error in function!");
        return 1;
    }

    puts(str);

    free(str);

    return 0;
}

程序输出

TwinPeaks

当然你可以使用标准字符串函数strcpystrcat代替可以在return语句中写入的循环

return result == NULL ? result : strcat( strcpy( result, s1 ), s2 ); 

答案 1 :(得分:0)

当您将新字符串复制到旧字符串时,您最终会在初始P之后插入空字符。您需要做的事情如下。

  1. malloc一个大小为maxcount的新缓冲区(ns)。

  2. strcpy s into ns

  3. strcpy ct into ns + strlen(s)

  4. 请注意。如果您不允许使用strcpy(),请以与safecpy()

    类似的方式将您自己的版本编写为函数safecat()
    1. return ns
    2. 请注意,如果您不再需要,请稍后在程序中释放ns。

答案 2 :(得分:0)

我认为你误解了malloc的含义。

您正在使用malloc,就像它会在字符串中或字符串末尾创建一个新插槽一样。但是,malloc(sizeX)会在内存中的某处保留一个新的内存块(sizeX个字节(而不是您可以确定的特定位置)。 malloc的结果是指向内存块的指针,而不是字符。

所以你对表达式*(s + i) = (char *) malloc((strlen(s) + strlen(ct) + 1) * sizeof(char));的处理实际上是将一个指针值(通常在被视为字符时看起来很模糊)作为值直接写入s位置的字符串s中字符串终止字符;

对于你的safecat,首先为新的连接结果字符串保留内存,然后用你的逻辑填充它(我想这是一个编程任务,你不能使用strcpy,对吧?

int slen = strlen(s);
int ctlen = strlen(ct);
char *result = (char *) malloc((slen + ctlen + 1) * sizeof(char));
for (int i=0; i<slen; i++)
  result[i] = s[i];
for (int i=0; i < ctlen + 1 ; i++) // note "i < ctlen + 1" for considering string terminator of ct.
  result[i+slen] = ct[i];

答案 3 :(得分:0)

感谢所有帮助过的人。这是一个编码任务,我能够在第二天弄明白。

我写的东西看起来似乎非常混乱,因为我刚刚学习了指针,是的,我不允许使用'strcat()'或'strcpy()'。