简体   繁体   English

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

[英]How can I use pointers received from a function correctly? (in C)

I've written a function called safecat that adds one string (called ct ) to the end of another string (called s ). 我编写了一个名为safecat的函数,该函数将一个字符串(称为ct )添加到另一个字符串(称为s )的末尾。 The resulting new s is then returned. 然后返回结果新s

In the main function my task is to check if my function worked the intended way, and if so, then print the result of my function safecat . 在主函数中,我的任务是检查函数是否按预期方式工作,如果可以,则打印函数safecat的结果。

The problem I have is that when I assign the return value of safecat to another char -string (in this case str ) in my main function, the stuff in str which comes from ct is just garbage. 我遇到的问题是,当我在我的主要函数safecat的返回值分配给另一个char -string(在这种情况下为str )时,来自ct str中的东西只是垃圾。 I don't understand where the problem is, if I just do printf("%s", safecat(s, ct)); 我不明白问题出在哪里,如果我只是做printf("%s", safecat(s, ct)); I get the correct result. 我得到正确的结果。

Here you see my code: 在这里,您可以看到我的代码:

#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;
}

I think the error happens when I assign safecat to str . 我认为将safecat分配给str时会发生错误。 When I print out str I get " TwinP' a " instead of " TwinPeaks ". 当我打印出str我得到的是“ TwinP' a ”而不是“ TwinPeaks ”。

Thanks for helping! 感谢您的帮助!

You can not change the size of the array 您不能更改数组的大小

char s[] = "Twin";

in the function using malloc . 在使用malloc的函数中。

And in any case this loop 无论如何,这个循环

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++;
}

does not make sense. 没有道理。 For example the expression *(s + i) has type char instead of the type char * . 例如,表达式*(s + i)具有char类型而不是char *类型。 And also it is not clear why a memory is allocated in each iteration of the loop. 同样也不清楚为什么在每次循环迭代中都分配一个内存。

A correct approach is to allocate dynamically a new array with the size equal to the sum of the sizes of the source arrays plus one and to copy the source arrays in the allocated array. 正确的方法是动态分配一个新数组,该数组的大小等于源数组的大小之和加1,然后在分配的数组中复制源数组。

Here is a demonstrative program that shows how it can be done. 这是一个演示程序,显示了如何完成它。 Also you should free the allocated memory when the array is not needed any more. 另外,当不再需要该阵列时,您应该释放分配的内存。

#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;
}

The program output is 程序输出为

TwinPeaks

Of course you could use standard string functions strcpy and strcat instead of the loops that can be both written even in the return statement 当然,您可以使用标准的字符串函数strcpystrcat来代替甚至可以在return语句中编写的循环

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

When you copy the new string to the old string you wind up putting in the null character after the initial P. What you need to do is as follows. 当您将新字符串复制到旧字符串时,最终会在初始P后面输入空字符。您需要执行以下操作。

  1. malloc a new buffer (ns) of the size of maxcount. malloc一个新的缓冲区(ns),其大小为maxcount。

  2. strcpy s into ns strcpy s到ns

  3. strcpy ct into ns + strlen(s) strcpy ct成ns + strlen(s)

Note. 注意。 If you are not allowed to used strcpy() , then write your own version as a function safecpy() in the a similar fashion to safecat() 如果不允许使用strcpy() ,请以与safecat()类似的方式将自己的版本编写为函数safecpy()

  1. return ns 返回ns

Note that you would want to free ns sometime later in the program if you no longer need it. 请注意,如果您以后不再需要ns,则希望在程序中的某个时间释放它。

I think that you misunderstand the meaning of malloc . 我认为您误解了malloc的含义。

You are using malloc as if it would make a new slot in or at the end of a string. 您正在使用malloc ,就像它将在字符串中或字符串末尾产生一个新槽一样。 malloc(sizeX) , however, reserves a new memory block with sizeX bytes somewhere in the memory (rather than at a particular position that you could determine). 但是, malloc(sizeX)在内存中某个位置(而不是您可以确定的特定位置malloc(sizeX)保留一个带有sizeX个字节的新内存块。 And the result of malloc is a pointer to a memory block, not a character. malloc的结果是指向内存块的指针,而不是字符。

So what you do with expression *(s + i) = (char *) malloc((strlen(s) + strlen(ct) + 1) * sizeof(char)); 所以你用表达式*(s + i) = (char *) malloc((strlen(s) + strlen(ct) + 1) * sizeof(char)); is actually writing a pointer value (usually something obscure when viewed as characters) as value directly into string s at the position of s 's string terminating character; 实际上ss的字符串终止字符位置将指针值(通常被视为字符时有些晦涩)直接写为s

For your safecat , first reserve memory for the new concatenated result string, then fill it up with your logic (I suppose this is a programming assignment and you are not allowed to use strcpy , right? 对于您的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];

Thank you to everyone who helped. 谢谢所有帮助的人。 It was a coding assignment and I was able to figure it out the next day. 这是一个编码任务,第二天我就知道了。

The stuff I've written must have seemed to be very chaotic as I've just learned about pointers, and yes, I was not allowed to use 'strcat()' or 'strcpy()'. 当我刚学习指针时,我写的东西似乎一定非常混乱,是的,不允许我使用'strcat()'或'strcpy()'。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM