Click here to Skip to main content
15,887,416 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello. I used to mainly use C++, I don't know much about C. Recently I came across a C language question, I really didn't understand it.
The question always told me that an access conflict occurred at the write location.

"parse.h":
C
struct query_parameter {
	const char* name;
	const char* value;
};



C
#include "parse.h"
int
parse_query_string(char* url, struct query_parameter** out)
{
	int status=0;
	int n = 0;
	int v = 0;
	char temp[] = {""};
	int count = 0;
	for (int i = 0; i < strlen(url); i++) {
		printf("\n%c %s\n", url[i],temp);
		if (status == 0 && url[i] == '?') {
			status = 1;
			n = 1;
			if (i < strlen(url)-1 && url[i + 1] != '=') {
				(*out) = (struct query_parameter*)malloc(sizeof(struct query_parameter) * 100);
				count += 1;
			}
			else return -1;
			continue;
		}
		if (status == 0) continue;
		if (n == 1) {
			if (url[i] == '=') {
				n = 0;
				v = 1;
				(*out)[count - 1].name = temp; --Here is where the problem occurs
				memset(temp, 0, sizeof(temp));
				if (i < strlen(url)-1 && url[i + 1] == '&') return -1;
		        continue;
			}
			char tempc[2];
			tempc[0] = url[i];
			tempc[1] = '\0';
			strcat(temp, tempc);
		}
        if (v == 1) {
			if (url[i] == '&') {
				n = 1;
				v = 0;
				(*out)[count - 1].value = temp;
				memset(temp, 0, sizeof(temp));
				if (i < strlen(url)-1 && url[i + 1] != '=') {
					count += 1;
					/*(*out) = (struct query_parameter*)realloc(sizeof(struct query_parameter) * count);*/
				}
				else return -1;
				continue;
			}
			char tempc[2];
			tempc[0] = url[i];
			tempc[1] = '\0';
			strcat(temp, tempc);
		}

	}
	if (status == 0) return -1;
	if (n == 1) return -1;
	if (v == 1) {
		if (strlen(temp) == 0) return -1;
		(*out)[count - 1].value = temp;
	}
	return count;
}


The main program is:
C
char url[]={"http://example.com/xxx?id=1234&data_type=article&user=john"};
struct query_parameter* params;
parse_query_string(url,& params);


I would appreciate it so much if you could find out what the problem is!

What I have tried:

Create memory for (*out).name first,
(*out).name=(char*) malloc(strlen(temp)+1)
still not working
Posted
Updated 9-Jun-23 5:25am
v4
Comments
Richard MacCutchan 9-Jun-23 10:39am    
What is this code supposed to be doing?
njukenanli 9-Jun-23 11:09am    
To extract name-value pairs after '?' from the url.
Then save them into the array-query_parameter* params.
one struct should be:
params[0].name=id
params[0].value=1234
Richard MacCutchan 9-Jun-23 11:12am    
Then I suggest you throw that code away. There is a much simpler way of parsing those fields by using the strtok function.
njukenanli 9-Jun-23 11:21am    
wow thank you! I haven't heard this func before. This would make my codes much simpler.
Richard MacCutchan 9-Jun-23 11:33am    
It's always worth spending time studying the documentation for any language you are trying to learn. There is a good reference at C reference - cppreference.com[^].

You have a problem with a buffer overflow:
C
char temp[] = { "" };  /* defines a single character string */
/* later on */
char tempc[2];  /* defines a 2 char string */
temp[0] = url[i];
temp[1] = '\0';
strcat(temp, tempc);  /* <- Here we attempt to append the 2 chars from tempc into temp, which is only 1 char long */
Interestingly, both gcc and clang will compile the code happily and not report this error. This is probably the source of the write error you're getting (MSVC ?)

However, gcc with -O1 does flag another bug:
warning: storing the address of local variable ‘temp’ in ‘*_35 + _38.value’ [-Wdangling-pointer=]
                        (*out)[count - 1].value = temp; 
                        ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
This means that the variable temp is on the stack, so it "disappears" after the function returns (not really, but for the sake of this discussion assume it does). So two issues here. If you try to access the value member of the out parameter after the function returns, it's unknown what happens. You may get a sensible value, you may get a garbage value, you may get a program crash. The other problem is that all of the elements of the out array get pointers to the same temp variable. That means as you modify the value of temp, every member of the array ends up with the same value of the value member. That's probably not what you want.
 
Share this answer
 
Comments
njukenanli 13-Jun-23 8:17am    
Thank you. Your advice has completely solved my problem. I think that my assignment of a local variable (string) to a name that will still be used after the function returns (a global variable) may be the source of the problem.
We can't tell - we can't run that code fragment in isolation, and the most likely thing is that the call to that function is passing in an invalid pointer.

So, it's going to be up to you.
Fortunately, you have a tool available to you which will help you find out what is going on: the debugger. How you use it depends on your compiler system, but a quick Google for the name of your IDE and "debugger" should give you the info you need.

Put a breakpoint on the first line in the function, and run your code through the debugger. Then look at your code, and at your data and work out what should happen manually. Then single step each line checking that what you expected to happen is exactly what did. When it isn't, that's when you have a problem, and you can back-track (or run it again and look more closely) to find out why.

Sorry, but we can't do that for you - time for you to learn a new (and very, very useful) skill: debugging!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900